AlbumShaper
1.0a3
|
Go to the source code of this file.
Functions | |
bool | scaleJPEG (QString fileIn, QImage &scaledImage, int targetWidth, int targetHeight) |
bool | transformJPEG (QString fileIn, QString fileOut, TRANSFORM_CODE transformation) |
bool scaleJPEG | ( | QString | fileIn, |
QImage & | scaledImage, | ||
int | targetWidth, | ||
int | targetHeight | ||
) |
Definition at line 54 of file jpegTools.cpp.
References GVJPEGFatalError::handler(), and GVJPEGFatalError::mJmpBuffer.
Referenced by scaleImage().
{ //get jpeg info struct jpeg_decompress_struct cinfo; //open file FILE* inputFile=fopen( fileIn.ascii(), "rb" ); if(!inputFile) return false; //error checking on jpg file struct GVJPEGFatalError jerr; cinfo.err = jpeg_std_error(&jerr); cinfo.err->error_exit = GVJPEGFatalError::handler; if (setjmp(jerr.mJmpBuffer)) { jpeg_destroy_decompress(&cinfo); fclose(inputFile); return false; } //get jpeg resolution jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, inputFile); jpeg_read_header(&cinfo, TRUE); //find optimal scale fraction (must be power of two) int origWidth = (int)cinfo.image_width; int origHeight = (int)cinfo.image_height; int num = 1; int denom = 1; //if image is bigger than target, scale down by adjusting the denominator if( origWidth > targetWidth || origHeight > targetHeight ) { while( denom < 8 && ( origWidth / (denom*2) >= targetWidth || origHeight / (denom*2) >= targetHeight ) ) { denom = denom*2; } } //set scaling fraction cinfo.scale_num=num; cinfo.scale_denom=denom; //create intermediary image scaled by power of 2 jpeg_start_decompress(&cinfo); switch(cinfo.output_components) { //Black and White Image case 1: { scaledImage.create( cinfo.output_width, cinfo.output_height, 8, 256 ); for (int i=0; i<256; i++) { scaledImage.setColor(i, qRgb(i,i,i)); } } break; //24 or 32 bit color image case 3: case 4: scaledImage.create( cinfo.output_width, cinfo.output_height, 32 ); break; //Unknown color depth default: jpeg_destroy_decompress(&cinfo); fclose(inputFile); return false; } //fast scale image uchar** lines = scaledImage.jumpTable(); while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height); } jpeg_finish_decompress(&cinfo); //expand 8 to 32bits per pixel since QImage wants 32 if ( cinfo.output_components == 1 ) { scaledImage = scaledImage.convertDepth( 32, Qt::AutoColor ); } //expand 24 to 32bits per pixel since QImage wants 32 if ( cinfo.output_components == 3 ) { for (uint j=0; j<cinfo.output_height; j++) { uchar *in = scaledImage.scanLine(j) + cinfo.output_width*3; QRgb *out = (QRgb*)( scaledImage.scanLine(j) ); for (uint i=cinfo.output_width; i--; ) { in-=3; out[i] = qRgb(in[0], in[1], in[2]); } } } //use slower smooth scale technique to scale to final size from intermediate image if( scaledImage.width() != targetWidth || scaledImage.height() != targetHeight ) { int clampedTargetWidth = targetWidth; int clampedTargetHeight = targetHeight; //clamp scaling up to < 2x if(QMIN( ((float)targetWidth)/origWidth, ((float)targetHeight)/origHeight ) > 2) { clampedTargetWidth = 2*origWidth; clampedTargetHeight = 2*origHeight; } scaledImage = scaledImage.smoothScale(clampedTargetWidth, clampedTargetHeight, QImage::ScaleMin); } jpeg_destroy_decompress(&cinfo); fclose(inputFile); return true; }
bool transformJPEG | ( | QString | fileIn, |
QString | fileOut, | ||
TRANSFORM_CODE | transformation | ||
) |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Definition at line 178 of file jpegTools.cpp.
References FLIP_H, FLIP_V, jpeg_transform_info::force_grayscale, jcopy_markers_execute(), jcopy_markers_setup(), JCOPYOPT_COMMENTS, jtransform_adjust_parameters(), jtransform_execute_transformation(), jtransform_request_workspace(), JXFORM_FLIP_H, JXFORM_FLIP_V, JXFORM_ROT_270, JXFORM_ROT_90, ROTATE_270, ROTATE_90, jpeg_transform_info::transform, and jpeg_transform_info::trim.
Referenced by transformImage().
{ struct jpeg_decompress_struct srcinfo; struct jpeg_compress_struct dstinfo; struct jpeg_error_mgr jsrcerr, jdsterr; FILE * input_file; FILE * output_file; jpeg_transform_info transformoption; jvirt_barray_ptr * src_coef_arrays; jvirt_barray_ptr * dst_coef_arrays; //setup transofrmation option struct, this was done in jpegtran by the //parse_switches function in jpegtran.c switch( transformation ) { case ROTATE_90: transformoption.transform = JXFORM_ROT_90; break; case ROTATE_270: transformoption.transform = JXFORM_ROT_270; break; case FLIP_H: transformoption.transform = JXFORM_FLIP_H; break; case FLIP_V: transformoption.transform = JXFORM_FLIP_V; break; default: return false; } transformoption.trim = TRUE; transformoption.force_grayscale = FALSE; // Initialize the JPEG decompression object with default error handling. srcinfo.err = jpeg_std_error(&jsrcerr); jpeg_create_decompress(&srcinfo); // Initialize the JPEG compression object with default error handling. dstinfo.err = jpeg_std_error(&jdsterr); jpeg_create_compress(&dstinfo); //what does this stuff do? dstinfo.err->trace_level = 0; jsrcerr.trace_level = jdsterr.trace_level; srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use; //open input and output files if ((input_file = fopen(QFile::encodeName(fileIn), "rb")) == NULL) return false; if ((output_file = fopen(QFile::encodeName(fileOut), "wb")) == NULL) return false; // Specify data source for decompression jpeg_stdio_src(&srcinfo, input_file); // Enable saving of extra markers that we want to copy jcopy_markers_setup(&srcinfo, JCOPYOPT_COMMENTS); // Read file header (void) jpeg_read_header(&srcinfo, TRUE); // Any space needed by a transform option must be requested before // jpeg_read_coefficients so that memory allocation will be done right. jtransform_request_workspace(&srcinfo, &transformoption); // Read source file as DCT coefficients src_coef_arrays = jpeg_read_coefficients(&srcinfo); // Initialize destination compression parameters from source values jpeg_copy_critical_parameters(&srcinfo, &dstinfo); // Adjust destination parameters if required by transform options; // also find out which set of coefficient arrays will hold the output. dst_coef_arrays = jtransform_adjust_parameters(&dstinfo, src_coef_arrays, &transformoption); // Specify data destination for compression jpeg_stdio_dest(&dstinfo, output_file); // Start compressor (note no image data is actually written here) jpeg_write_coefficients(&dstinfo, dst_coef_arrays); // Copy to the output file any extra markers that we want to preserve jcopy_markers_execute(&srcinfo, &dstinfo); // Execute image transformation, if any jtransform_execute_transformation(&srcinfo, &dstinfo, src_coef_arrays, &transformoption); // Finish compression and release memory jpeg_finish_compress(&dstinfo); jpeg_destroy_compress(&dstinfo); (void) jpeg_finish_decompress(&srcinfo); jpeg_destroy_decompress(&srcinfo); // Close files fclose(input_file); fclose(output_file); //success return true; }