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

jpegTools.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

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)


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(), 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 Wed May 4 11:10:32 2005 for AlbumShaper by  doxygen 1.3.9.1