00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "plstdpch.h"
00015
00016 #include <stdio.h>
00017
00018 extern "C"
00019 {
00020 #include "jpeglib.h"
00021 }
00022
00023 #include "pljpegenc.h"
00024 #include "plexcept.h"
00025 #include "jmemdest.h"
00026
00027
00028 #define JPEG_INTERNALS
00029 #include <jmorecfg.h>
00030
00031
00033
00034
00035 METHODDEF(void)
00036 error_exit (j_common_ptr pcinfo)
00037
00038
00039 {
00040
00041 char sz[256];
00042 (pcinfo->err->format_message) (pcinfo, sz);
00043 strcat (sz, "\n");
00044
00045 PLPicEncoder::raiseError (PL_ERRFORMAT_NOT_SUPPORTED, sz);
00046 }
00047
00049
00050
00051 PLJPEGEncoder::PLJPEGEncoder
00052 ()
00053 : PLPicEncoder(),
00054 m_pcinfo ( new jpeg_compress_struct ),
00055 m_pjerr ( new jpeg_error_mgr ),
00056 iQuality_ (0),
00057 bOptimizeCoding_ (false),
00058 iSmoothingFactor_ (0),
00059 uiDensityX_ (0),
00060 uiDensityY_ (0)
00061
00062 {
00063 m_pcinfo->err = jpeg_std_error (m_pjerr);
00064 m_pjerr->error_exit = error_exit;
00065
00066 jpeg_create_compress (m_pcinfo);
00067 }
00068
00069
00070 PLJPEGEncoder::~PLJPEGEncoder
00071 ()
00072 {
00073 jpeg_destroy_compress (m_pcinfo);
00074 delete m_pjerr;
00075 delete m_pcinfo;
00076 }
00077
00078 void PLJPEGEncoder::DoEncode
00079 ( PLBmp * pBmp,
00080 PLDataSink * pDataSink
00081 )
00082 {
00083 PLASSERT (pBmp->GetBitsPerPixel() == 32);
00084 try
00085 {
00086
00087
00088
00089
00090
00091
00092
00093 jpeg_mem_dest(m_pcinfo, pDataSink->GetBufferPtr(), pDataSink->GetMaxDataSize(), pDataSink);
00094
00095
00096 m_pcinfo->image_width = pBmp->GetWidth();
00097 m_pcinfo->image_height = pBmp->GetHeight();
00098
00099 m_pcinfo->input_components = RGB_PIXELSIZE;
00100 m_pcinfo->in_color_space = JCS_RGB;
00101
00102 jpeg_set_defaults (m_pcinfo);
00103
00104 m_pcinfo->X_density = pBmp->GetResolution().x;
00105 m_pcinfo->Y_density = pBmp->GetResolution().y;
00106
00107
00108 m_pcinfo->dct_method = JDCT_FLOAT;
00109
00110
00111 if (iQuality_)
00112 jpeg_set_quality(m_pcinfo, iQuality_, true);
00113 m_pcinfo->optimize_coding = bOptimizeCoding_;
00114 m_pcinfo->smoothing_factor = iSmoothingFactor_;
00115
00116 if (uiDensityX_ || uiDensityY_)
00117 {
00118 m_pcinfo->density_unit = 1;
00119 m_pcinfo->X_density = uiDensityX_;
00120 m_pcinfo->Y_density = uiDensityY_;
00121 }
00122
00123 jpeg_start_compress (m_pcinfo,true);
00124
00125 encodeRGB (pBmp, pBmp->GetHeight());
00126
00127 jpeg_finish_compress (m_pcinfo);
00128 }
00129 catch (PLTextException)
00130 {
00131 jpeg_abort_compress(m_pcinfo);
00132 throw;
00133 }
00134
00135 }
00136
00137
00138
00139 void PLJPEGEncoder::encodeRGB
00140 ( PLBmp * pBmp,
00141 int iScanLines
00142 )
00143
00144 {
00145
00146 PLBYTE * pBuf = NULL;
00147 int CurLine = 0;
00148 JSAMPARRAY ppBuf = &pBuf;
00149
00150 pBmp->Lock(true, false);
00151 PLPixel32 ** pLineArray = pBmp->GetLineArray32();
00152
00153 #if ((PL_RGBA_RED!=RGB_RED)||(PL_RGBA_GREEN!=RGB_GREEN)||(PL_RGBA_BLUE!=RGB_BLUE)||(4!=RGB_PIXELSIZE))
00154 pBuf = new PLBYTE [pBmp->GetWidth()*RGB_PIXELSIZE];
00155 #endif
00156
00157 int written = 0;
00158 while (CurLine < iScanLines)
00159 {
00160 #if ((PL_RGBA_RED!=RGB_RED)||(PL_RGBA_GREEN!=RGB_GREEN)||(PL_RGBA_BLUE!=RGB_BLUE)||(4!=RGB_PIXELSIZE))
00161 int i;
00162 for (i=0;i<pBmp->GetWidth();i++)
00163 {
00164
00165 PLPixel32 * pSrcPixel = pLineArray[CurLine]+i;
00166 PLBYTE * pDestPixel = pBuf+i*RGB_PIXELSIZE;
00167 pDestPixel[RGB_RED] = pSrcPixel->GetR();
00168 pDestPixel[RGB_GREEN] = pSrcPixel->GetG();
00169 pDestPixel[RGB_BLUE] = pSrcPixel->GetB();
00170 }
00171 jpeg_write_scanlines (m_pcinfo, ppBuf, 1);
00172 CurLine++;
00173 #else
00174 written = jpeg_write_scanlines (m_pcinfo,&pLineArray[CurLine], 32);
00175 CurLine+=written;
00176
00177 if(!written)
00178 break;
00179 #endif
00180 }
00181 pBmp->Unlock();
00182 if(pBuf)
00183 {
00184 delete[] pBuf;
00185 }
00186 }
00187
00189
00190 void PLJPEGEncoder::SetQuality(int iQuality)
00191 {
00192 iQuality_ = iQuality;
00193 }
00194
00195 void PLJPEGEncoder::SetOptimizeCoding(bool bOptimizeCoding)
00196 {
00197 bOptimizeCoding_ = bOptimizeCoding;
00198 }
00199
00200 void PLJPEGEncoder::SetSmoothingFactor(int iSmoothingFactor)
00201 {
00202 iSmoothingFactor_ = iSmoothingFactor;
00203 }
00204
00205 void PLJPEGEncoder::SetDensity(unsigned int uiX, unsigned int uiY)
00206 {
00207 uiDensityX_ = uiX;
00208 uiDensityY_ = uiY;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284