/* Copyright (c) 1999 Surendar Chandra and Duke University * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Duke University * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE */ /* Usage: unsigned int initialQualityFactor(struct jpeg_decompress_struct dinfo) Compile with IJG JPEG Library version 6a or higher. */ #include #include #include #include #include #include #include #include #include "common.h" /* ALL_TABLE - Compute the quality factor as a average of all Quant table values. Usually computing the value for just a single representative Quant table entry is enough and so this may be safely undefined. */ #undef ALL_TABLE /* The representative index if not using ALL_TABLE. 2 seems to work best */ #define USE_INDEX 2 /* We can either use the Luminance table or Chrominance table. There are no chrominance tables for GrayScale JPEGs and so using Luminance table is preferred */ #define USE_LUMINANCE_TABLE #define DCTSIZE2 64 unsigned int initialQualityFactor(struct jpeg_decompress_struct dinfo) { JQUANT_TBL *qt; unsigned int initQ = 0; unsigned int temp; /* Standard JPEG Luminance and Chrominance Quantization tables */ #ifdef USE_LUMINANCE_TABLE static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99 }; #else static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }; #endif /* USE_LUMINANCE_TABLE */ #ifdef USE_LUMINANCE_TABLE qt = dinfo.quant_tbl_ptrs[0]; #else /* USE_LUMINANCE_TABLE */ qt = dinfo.quant_tbl_ptrs[1]; #endif /* USE_LUMINANCE_TABLE */ #ifdef ALL_TABLE for (int index=0; index < DCTSIZE2;index++) { temp = ((qt->quantval[index] * 100L) - 50L) / std_luminance_quant_tbl[index]; if (temp <= 100) temp = (200 - temp) / 2; else temp = 5000 / temp; initQ+=temp; } initQ /= DCTSIZE2; #else temp = ((qt->quantval[USE_INDEX] * 100L) - 50L) / std_luminance_quant_tbl[USE_INDEX]; if (temp <= 100) temp = (200 - temp) / 2; else temp = 5000 / temp; initQ = temp; #endif /* ALL_TABLE */ return initQ; } #undef DEBUG #ifdef DEBUG int main(int argc, char *argv[], char *envp[]) { FILE * infile; /* source file */ struct jpeg_decompress_struct dinfo; struct jpeg_error_mgr jerr; if (argc != 2) { fprintf(stderr, "Usage: %s \n", *argv); exit(0); } if ((infile = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "can't open %s\n", argv[1]); exit(0); } /* We set up the normal JPEG error routines, then override error_exit. */ dinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&dinfo); jpeg_stdio_src(&dinfo, infile); (void) jpeg_read_header(&dinfo, TRUE); printf("JPEG Quality Factor: %d\n", initialQualityFactor(dinfo)); jpeg_destroy_decompress(&dinfo); exit(0); } #endif /* DEBUG */