00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "plstdpch.h"
00018 #include "plpicdec.h"
00019 #include "plfilesrc.h"
00020 #ifdef _WINDOWS
00021 #include "plressrc.h"
00022 #endif
00023 #include "plmemsrc.h"
00024 #include "plexcept.h"
00025 #include "planybmp.h"
00026
00027 #include <stdio.h>
00028
00029
00030
00031 int PLPicDecoder::m_TraceLevel = 0;
00032 char * PLPicDecoder::m_pszTraceFName = NULL;
00033
00034
00035 PLPicDecoder::PLPicDecoder
00036 () : PLObject(),
00037 m_pDataSrc (0)
00038
00039 {
00040 }
00041
00042
00043 PLPicDecoder::~PLPicDecoder
00044 ()
00045 {
00046 if (m_pszTraceFName)
00047 delete [] m_pszTraceFName;
00048 m_pszTraceFName = NULL;
00049 }
00050
00051
00052 void PLPicDecoder::MakeBmpFromFile
00053 ( const char * pszFName,
00054 PLBmp * pBmp,
00055 int BPPWanted,
00056 PLIProgressNotification * pProgNot
00057 )
00058
00059
00060 {
00061 try
00062 {
00063 OpenFile (pszFName, pProgNot);
00064 MakeBmp (m_pDataSrc, pBmp, BPPWanted);
00065 Close();
00066 }
00067 catch (PLTextException)
00068 {
00069
00070 if (m_pDataSrc) delete m_pDataSrc;
00071 throw;
00072 }
00073 }
00074
00075 #ifdef _WINDOWS
00076 void PLPicDecoder::MakeBmpFromResource
00077 ( HINSTANCE hInstResource, int ResourceID,
00078 PLBmp * pBmp,
00079 int BPPWanted,
00080 const char * ResType,
00081 HMODULE hResModule
00082 )
00083
00084
00085 {
00086 PLResourceSource * pResSrc = NULL;
00087 int err;
00088
00089 char sz[256];
00090 sprintf (sz, "--- Decoding resource ID %i. ---\n", ResourceID);
00091 Trace (1, sz);
00092
00093 try
00094 {
00095 pResSrc = new PLResourceSource ();
00096 err = pResSrc->Open (hInstResource, ResourceID, ResType);
00097 if (err)
00098 {
00099 sprintf (sz, "Opening resource %i failed", ResourceID);
00100 raiseError (err, sz);
00101 }
00102
00103 MakeBmp (pResSrc, pBmp, BPPWanted);
00104 pResSrc->Close ();
00105 }
00106 catch (PLTextException)
00107 {
00108
00109 if (pResSrc) delete pResSrc;
00110 throw;
00111 }
00112
00113
00114 delete pResSrc;
00115 }
00116 #endif
00117
00118
00119 void PLPicDecoder::MakeBmpFromMemory
00120 ( unsigned char * ucMemSrc,
00121 int MemSrcSize,
00122 PLBmp * pBmp,
00123 int BPPWanted,
00124 PLIProgressNotification * pProgNot
00125 )
00126
00127
00128 {
00129 PLMemSource * pMemSrc = NULL;
00130 int err;
00131
00132 char sz[256];
00133 sprintf (sz, "--- Decoding from memory at %p. ---\n", ucMemSrc);
00134 Trace (1, sz);
00135
00136 try
00137 {
00138 pMemSrc = new PLMemSource ();
00139 err = pMemSrc->Open (ucMemSrc, MemSrcSize);
00140 if (err)
00141 {
00142 sprintf (sz, "Reading from memory at %p failed", ucMemSrc);
00143 raiseError (err, sz);
00144 }
00145
00146 MakeBmp (pMemSrc, pBmp, BPPWanted);
00147 pMemSrc->Close ();
00148 }
00149 catch (PLTextException)
00150 {
00151
00152 if (pMemSrc) delete pMemSrc;
00153 throw;
00154 }
00155
00156
00157 delete pMemSrc;
00158 }
00159
00160
00161 void PLPicDecoder::MakeBmp
00162 ( PLDataSource * pDataSrc,
00163 PLBmp * pBmp,
00164 int BPPWanted
00165 )
00166
00167
00168 {
00169 DoDecode (pBmp, pDataSrc);
00170 if (BPPWanted != 0) {
00171 if (BPPWanted > pBmp->GetBitsPerPixel()) {
00172 PLAnyBmp TempBmp;
00173 TempBmp.CreateCopy (*pBmp, BPPWanted);
00174 *pBmp = TempBmp;
00175 } else if (BPPWanted < pBmp->GetBitsPerPixel()) {
00176 throw (PLTextException (PL_ERRFORMAT_NOT_SUPPORTED, "Image bit depth doesn't match request."));
00177 }
00178 }
00179 }
00180
00181 void PLPicDecoder::SetTraceConfig
00182 ( int Level,
00183 char * pszFName
00184 )
00185 {
00186
00187 PLASSERT (Level < 4);
00188
00189 m_TraceLevel = Level;
00190
00191 if (m_pszTraceFName)
00192 delete [] m_pszTraceFName;
00193
00194 if (pszFName)
00195 {
00196 m_pszTraceFName = new char[strlen (pszFName)+1];
00197 strcpy (m_pszTraceFName, pszFName);
00198
00199
00200 remove (m_pszTraceFName);
00201 }
00202 else
00203 m_pszTraceFName = NULL;
00204 }
00205
00206 void PLPicDecoder::OpenFile
00207 ( const char * pszFName,
00208 PLIProgressNotification * pProgNot
00209 )
00210 {
00211 int err;
00212
00213 char sz[1024];
00214 sprintf (sz, "--- Decoding file %s. ---\n", pszFName);
00215 Trace (1, sz);
00216
00217 try
00218 {
00219 PLFileSource * pFileSrc = new PLFileSource (pProgNot);
00220 m_pDataSrc = pFileSrc;
00221 err = pFileSrc->Open (pszFName);
00222 if (err)
00223 {
00224 sprintf (sz, "Opening %s failed", pszFName);
00225 raiseError (err, sz);
00226 }
00227
00228 }
00229 catch (PLTextException)
00230 {
00231 if (m_pDataSrc)
00232 delete m_pDataSrc;
00233 m_pDataSrc = 0;
00234 throw;
00235 }
00236 }
00237
00238 void PLPicDecoder::Close
00239 ()
00240 {
00241 m_pDataSrc->Close ();
00242 delete m_pDataSrc;
00243 m_pDataSrc = 0;
00244 }
00245
00246 void PLPicDecoder::raiseError
00247 ( int Code,
00248 char * pszErr
00249 )
00250
00251
00252
00253 {
00254 char sz[256];
00255 sprintf (sz, "Decoder error: %s\n", pszErr);
00256 Trace (0, sz);
00257 throw (PLTextException (Code, sz));
00258 }
00259
00260 void PLPicDecoder::Trace
00261 ( int TraceLevel,
00262 const char * pszMessage
00263 )
00264
00265 {
00266 if (TraceLevel <= m_TraceLevel)
00267 {
00268 if (m_pszTraceFName)
00269 {
00270
00271
00272 FILE * pFile = fopen (m_pszTraceFName, "a+t");
00273 if (pFile != (FILE *)0)
00274 {
00275 fprintf (pFile, pszMessage);
00276 fclose (pFile);
00277 }
00278 else
00279 {
00280 PLTRACE ("Error opening Trace file!\n");
00281 }
00282 }
00283 else
00284 PLTRACE (pszMessage);
00285 }
00286 }
00287
00288 void PLPicDecoder::DoDecode
00289 ( PLBmp * pBmp,
00290 PLDataSource * pDataSrc
00291 )
00292
00293
00294
00295 {
00296
00297
00298
00299 PLASSERT (false);
00300 }
00301
00302 PLBYTE * PLPicDecoder::unpackPictRow
00303 ( PLBYTE * pLineBuf,
00304 PLDataSource * pDataSrc,
00305 int Width,
00306 int rowBytes,
00307 int SrcBytes
00308 )
00309 {
00310 PLBYTE * pRawLine = pLineBuf;
00311
00312 if (rowBytes < 8)
00313 {
00314 pRawLine = pDataSrc->ReadNBytes (rowBytes);
00315 }
00316 else
00317 {
00318 PLBYTE * pSrcLine = pDataSrc->ReadNBytes(SrcBytes);
00319 PLBYTE * pCurPixel = pRawLine;
00320
00321
00322 for (int j = 0; j < SrcBytes; )
00323 {
00324 PLBYTE FlagCounter = pSrcLine[j];
00325 if (FlagCounter & 0x80)
00326 {
00327 if (FlagCounter == 0x80)
00328
00329
00330 j++;
00331 else
00332 {
00333 int len = ((FlagCounter ^ 255) & 255) + 2;
00334
00335 memset (pCurPixel, *(pSrcLine+j+1), len);
00336 pCurPixel += len;
00337 j += 2;
00338 }
00339 }
00340 else
00341 {
00342 int len = (FlagCounter & 255) + 1;
00343 memcpy (pCurPixel, pSrcLine+j+1, len);
00344 pCurPixel += len;
00345 j += len + 1;
00346 }
00347 }
00348 }
00349 return pRawLine;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414