I used libjpeg to complete this work, maybe you can refer to my code
#include <stdio.h> #include <math.h> #include "jpeglib.h" #include <setjmp.h> 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 }; int ReadJpegQuality(const char *filename) { FILE * infile = fopen(filename, "rb"); fseek(infile,0,SEEK_END); size_t sz = ftell(infile); fseek(infile,0,SEEK_SET); unsigned char* buffer = new unsigned char[sz]; fread(buffer,1,sz,infile); fclose(infile); struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpeg_mem_src(&cinfo,(unsigned char*)buffer,sz); jpeg_read_header(&cinfo, TRUE); int tmp_quality = 0; int linear_quality = 0; const int aver_times = 3; int times = 0; int aver_quality = 0; for(int i=0;i<DCTSIZE2;i++) { long temp = cinfo.quant_tbl_ptrs[0]->quantval[i]; if(temp<32767L&&temp>0) { linear_quality = ceil((float)(temp*100L - 50L)/std_luminance_quant_tbl[i]); if(linear_quality==1) tmp_quality = 1; else if(linear_quality==100) tmp_quality = 100; else if(linear_quality>100) { tmp_quality = ceil((float)5000/linear_quality); } else { tmp_quality = 100 - ceil((float)linear_quality/2); } aver_quality += tmp_quality; if(aver_times==++times) { aver_quality /= aver_times; break; } } } jpeg_destroy_decompress(&cinfo); return aver_quality; } int main(int argc,char** argv) { printf("quality: %d\n",ReadJpegQuality("test1.jpg")); return 0; }
this method uses libjpeg to read the quantization table of the jpg file, and then uses the quantization table to calculate quality arguments.