Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

jpegTools.cpp File Reference

#include <qglobal.h>
#include <stdio.h>
#include <qfileinfo.h>
#include <qstring.h>
#include <qimage.h>
#include <setjmp.h>
#include <jpeglib.h>
#include "jpegInternal.h"
#include "../imageTools.h"
#include "jpegTools.h"

Include dependency graph for jpegTools.cpp:

Go to the source code of this file.

Classes

struct  GVJPEGFatalError

Defines

#define XMD_H

Functions

bool scaleJPEG (QString fileIn, QImage &scaledImage, int targetWidth, int targetHeight)
bool transformJPEG (QString fileIn, QString fileOut, TRANSFORM_CODE transformation)


Define Documentation

#define XMD_H
 

Definition at line 30 of file jpegTools.cpp.


Function Documentation

bool scaleJPEG QString  fileIn,
QImage &  scaledImage,
int  targetWidth,
int  targetHeight
 

Definition at line 54 of file jpegTools.cpp.

References GVJPEGFatalError::mJmpBuffer.

Referenced by scaleImage().

00056 { 00057 //get jpeg info 00058 struct jpeg_decompress_struct cinfo; 00059 00060 //open file 00061 FILE* inputFile=fopen( fileIn.ascii(), "rb" ); 00062 if(!inputFile) return false; 00063 00064 //error checking on jpg file 00065 struct GVJPEGFatalError jerr; 00066 cinfo.err = jpeg_std_error(&jerr); 00067 cinfo.err->error_exit = GVJPEGFatalError::handler; 00068 if (setjmp(jerr.mJmpBuffer)) 00069 { 00070 jpeg_destroy_decompress(&cinfo); 00071 fclose(inputFile); 00072 return false; 00073 } 00074 00075 //get jpeg resolution 00076 jpeg_create_decompress(&cinfo); 00077 jpeg_stdio_src(&cinfo, inputFile); 00078 jpeg_read_header(&cinfo, TRUE); 00079 00080 //find optimal scale fraction (must be power of two) 00081 int origWidth = (int)cinfo.image_width; 00082 int origHeight = (int)cinfo.image_height; 00083 int num = 1; 00084 int denom = 1; 00085 00086 //if image is bigger than target, scale down by adjusting the denominator 00087 if( origWidth > targetWidth || origHeight > targetHeight ) 00088 { 00089 while( denom < 8 && 00090 ( origWidth / (denom*2) >= targetWidth || origHeight / (denom*2) >= targetHeight ) 00091 ) 00092 { denom = denom*2; } 00093 } 00094 00095 //set scaling fraction 00096 cinfo.scale_num=num; 00097 cinfo.scale_denom=denom; 00098 00099 //create intermediary image scaled by power of 2 00100 jpeg_start_decompress(&cinfo); 00101 00102 switch(cinfo.output_components) 00103 { 00104 //Black and White Image 00105 case 1: 00106 { 00107 scaledImage.create( cinfo.output_width, cinfo.output_height, 8, 256 ); 00108 for (int i=0; i<256; i++) 00109 { 00110 scaledImage.setColor(i, qRgb(i,i,i)); 00111 } 00112 } 00113 break; 00114 00115 //24 or 32 bit color image 00116 case 3: 00117 case 4: 00118 scaledImage.create( cinfo.output_width, cinfo.output_height, 32 ); 00119 break; 00120 00121 //Unknown color depth 00122 default: 00123 jpeg_destroy_decompress(&cinfo); 00124 fclose(inputFile); 00125 return false; 00126 } 00127 00128 //fast scale image 00129 uchar** lines = scaledImage.jumpTable(); 00130 while (cinfo.output_scanline < cinfo.output_height) 00131 { 00132 jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height); 00133 } 00134 jpeg_finish_decompress(&cinfo); 00135 00136 00137 //expand 8 to 32bits per pixel since QImage wants 32 00138 if ( cinfo.output_components == 1 ) 00139 { 00140 scaledImage = scaledImage.convertDepth( 32, Qt::AutoColor ); 00141 } 00142 00143 //expand 24 to 32bits per pixel since QImage wants 32 00144 if ( cinfo.output_components == 3 ) 00145 { 00146 for (uint j=0; j<cinfo.output_height; j++) 00147 { 00148 uchar *in = scaledImage.scanLine(j) + cinfo.output_width*3; 00149 QRgb *out = (QRgb*)( scaledImage.scanLine(j) ); 00150 00151 for (uint i=cinfo.output_width; i--; ) 00152 { 00153 in-=3; 00154 out[i] = qRgb(in[0], in[1], in[2]); 00155 } 00156 } 00157 } 00158 00159 //use slower smooth scale technique to scale to final size from intermediate image 00160 if( scaledImage.width() != targetWidth || scaledImage.height() != targetHeight ) 00161 { 00162 int clampedTargetWidth = targetWidth; 00163 int clampedTargetHeight = targetHeight; 00164 //clamp scaling up to < 2x 00165 if(QMIN( ((float)targetWidth)/origWidth, ((float)targetHeight)/origHeight ) > 2) 00166 { 00167 clampedTargetWidth = 2*origWidth; 00168 clampedTargetHeight = 2*origHeight; 00169 } 00170 00171 scaledImage = scaledImage.smoothScale(clampedTargetWidth, clampedTargetHeight, QImage::ScaleMin); 00172 } 00173 jpeg_destroy_decompress(&cinfo); 00174 fclose(inputFile); 00175 return true; 00176 }

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().

00179 { 00180 struct jpeg_decompress_struct srcinfo; 00181 struct jpeg_compress_struct dstinfo; 00182 struct jpeg_error_mgr jsrcerr, jdsterr; 00183 FILE * input_file; 00184 FILE * output_file; 00185 jpeg_transform_info transformoption; 00186 jvirt_barray_ptr * src_coef_arrays; 00187 jvirt_barray_ptr * dst_coef_arrays; 00188 00189 //setup transofrmation option struct, this was done in jpegtran by the 00190 //parse_switches function in jpegtran.c 00191 switch( transformation ) 00192 { 00193 case ROTATE_90: 00194 transformoption.transform = JXFORM_ROT_90; 00195 break; 00196 case ROTATE_270: 00197 transformoption.transform = JXFORM_ROT_270; 00198 break; 00199 case FLIP_H: 00200 transformoption.transform = JXFORM_FLIP_H; 00201 break; 00202 case FLIP_V: 00203 transformoption.transform = JXFORM_FLIP_V; 00204 break; 00205 default: 00206 return false; 00207 } 00208 transformoption.trim = TRUE; 00209 transformoption.force_grayscale = FALSE; 00210 00211 // Initialize the JPEG decompression object with default error handling. 00212 srcinfo.err = jpeg_std_error(&jsrcerr); 00213 jpeg_create_decompress(&srcinfo); 00214 00215 // Initialize the JPEG compression object with default error handling. 00216 dstinfo.err = jpeg_std_error(&jdsterr); 00217 jpeg_create_compress(&dstinfo); 00218 00220 //what does this stuff do? 00221 dstinfo.err->trace_level = 0; 00222 jsrcerr.trace_level = jdsterr.trace_level; 00223 srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use; 00225 00226 //open input and output files 00227 if ((input_file = fopen(QFile::encodeName(fileIn), "rb")) == NULL) return false; 00228 if ((output_file = fopen(QFile::encodeName(fileOut), "wb")) == NULL) return false; 00229 00230 // Specify data source for decompression 00231 jpeg_stdio_src(&srcinfo, input_file); 00232 00233 // Enable saving of extra markers that we want to copy 00234 jcopy_markers_setup(&srcinfo, JCOPYOPT_COMMENTS); 00235 00236 // Read file header 00237 (void) jpeg_read_header(&srcinfo, TRUE); 00238 00239 // Any space needed by a transform option must be requested before 00240 // jpeg_read_coefficients so that memory allocation will be done right. 00241 jtransform_request_workspace(&srcinfo, &transformoption); 00242 00243 // Read source file as DCT coefficients 00244 src_coef_arrays = jpeg_read_coefficients(&srcinfo); 00245 00246 // Initialize destination compression parameters from source values 00247 jpeg_copy_critical_parameters(&srcinfo, &dstinfo); 00248 00249 // Adjust destination parameters if required by transform options; 00250 // also find out which set of coefficient arrays will hold the output. 00251 dst_coef_arrays = jtransform_adjust_parameters(&dstinfo, src_coef_arrays, 00252 &transformoption); 00253 00254 // Specify data destination for compression 00255 jpeg_stdio_dest(&dstinfo, output_file); 00256 00257 // Start compressor (note no image data is actually written here) 00258 jpeg_write_coefficients(&dstinfo, dst_coef_arrays); 00259 00260 // Copy to the output file any extra markers that we want to preserve 00261 jcopy_markers_execute(&srcinfo, &dstinfo); 00262 00263 // Execute image transformation, if any 00264 jtransform_execute_transformation(&srcinfo, &dstinfo, 00265 src_coef_arrays, 00266 &transformoption); 00267 00268 // Finish compression and release memory 00269 jpeg_finish_compress(&dstinfo); 00270 jpeg_destroy_compress(&dstinfo); 00271 (void) jpeg_finish_decompress(&srcinfo); 00272 jpeg_destroy_decompress(&srcinfo); 00273 00274 // Close files 00275 fclose(input_file); 00276 fclose(output_file); 00277 00278 //success 00279 return true; 00280 }


Generated on Sun Mar 4 19:43:00 2007 for AlbumShaper by doxygen 1.3.7