00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "plstdpch.h"
00020 #include "config.h"
00021 #include "plpictdec.h"
00022 #ifdef PL_SUPPORT_JPEG
00023 #include "pljpegdec.h"
00024 #endif
00025 #include "ploptable.h"
00026 #include "plexcept.h"
00027
00028 #include <stdio.h>
00029
00030 PLPictDecoder::PLPictDecoder
00031 ( PLJPEGDecoder * pJPEGDecoder
00032 )
00033 : PLPicDecoder(),
00034 m_pJPEGDecoder (pJPEGDecoder),
00035 m_Resolution(0,0)
00036
00037 {
00038 }
00039
00040
00041 PLPictDecoder::~PLPictDecoder
00042 ()
00043 {
00044 }
00045
00046
00047 void PLPictDecoder::DoDecode
00048 ( PLBmp * pBmp,
00049 PLDataSource * pDataSrc
00050 )
00051
00052 {
00053 int Version;
00054
00055 Trace (2, "Decoding mac pict.\n");
00056
00057
00058 pDataSrc->Skip (512);
00059
00060
00061 readHeader (pDataSrc, Version);
00062
00063 interpretOpcodes (pBmp, pDataSrc, Version);
00064 pBmp->SetResolution (m_Resolution);
00065 }
00066
00067 void PLPictDecoder::readHeader
00068 ( PLDataSource * pDataSrc,
00069 int& Version
00070 )
00071
00072
00073 {
00074 PLBYTE ch;
00075 PLWORD PicSize;
00076 char sz[256];
00077 MacRect Frame;
00078
00079 PicSize = ReadMWord (pDataSrc);
00080
00081 readRect (&Frame, pDataSrc);
00082
00083 while ((ch = ReadByte(pDataSrc)) == 0);
00084 if (ch != 0x11)
00085 raiseError (PL_ERRWRONG_SIGNATURE,
00086 "Error decoding pict: Version number missing.");
00087
00088 switch (ReadByte(pDataSrc))
00089 {
00090 case 1:
00091 Version = 1;
00092 break;
00093 case 2:
00094 if (ReadByte(pDataSrc) != 0xff)
00095 raiseError (PL_ERRWRONG_SIGNATURE,
00096 "Illegal version number.");
00097 Version = 2;
00098 break;
00099 default:
00100 raiseError (PL_ERRWRONG_SIGNATURE,
00101 "Illegal version number.");
00102 }
00103
00104 sprintf (sz, "PICT version %d found.\n", Version);
00105 Trace (2, sz);
00106 }
00107
00108
00109 void PLPictDecoder::interpretOpcodes
00110 ( PLBmp * pBmp,
00111 PLDataSource * pDataSrc,
00112 int& Version
00113 )
00114
00115
00116
00117
00118 {
00119 PLWORD Opcode;
00120 char sz[256];
00121
00122 bool bDone = false;
00123
00124 while (!bDone)
00125 {
00126 Opcode = readOpcode(Version, pDataSrc);
00127
00128 if (Opcode == 0xFF || Opcode == 0xFFFF)
00129 {
00130 bDone = true;
00131 Trace (2, "Opcode: End of pict.\n");
00132 raiseError (PL_ERRFORMAT_NOT_SUPPORTED,
00133 "PICT contained only vector data!\n");
00134 }
00135 else if (Opcode < 0xa2)
00136 {
00137 if (!strcmp(optable[Opcode].name, "reserved"))
00138 sprintf (sz, "Opcode: reserved=0x%x\n", Opcode);
00139 else
00140 sprintf (sz, "Opcode: %s\n", optable[Opcode].name);
00141 Trace (2, sz);
00142
00143 switch (Opcode)
00144 {
00145 case 0x01:
00146 clip (pDataSrc);
00147 break;
00148 case 0x12:
00149 case 0x13:
00150 case 0x14:
00151 pixPat (pDataSrc);
00152 break;
00153 case 0x70:
00154 case 0x71:
00155 case 0x72:
00156 case 0x73:
00157 case 0x74:
00158 case 0x75:
00159 case 0x76:
00160 case 0x77:
00161 skipPolyOrRegion (pDataSrc);
00162 break;
00163 case 0x90:
00164 case 0x98:
00165 bitsRect (pDataSrc, pBmp);
00166 bDone = true;
00167 break;
00168 case 0x91:
00169 case 0x99:
00170 bitsRegion (pDataSrc, pBmp);
00171 bDone = true;
00172 break;
00173 case 0x9a:
00174 opcode9a (pDataSrc, pBmp);
00175 bDone = true;
00176 break;
00177 case 0xa1:
00178 longComment (pDataSrc);
00179 break;
00180 default:
00181
00182 if (optable[Opcode].len == WORD_LEN)
00183 pDataSrc->Skip(ReadMWord(pDataSrc));
00184 else
00185 pDataSrc->Skip(optable[Opcode].len);
00186 }
00187 }
00188 else if (Opcode == 0xc00)
00189 {
00190 Trace (2, "Opcode: Header.\n");
00191 headerOp (pDataSrc, pBmp);
00192 }
00193 else if (Opcode == 0x8200)
00194 {
00195 Trace (2, "Opcode: JPEG.\n");
00196 jpegOp (pDataSrc, pBmp);
00197 bDone = true;
00198 }
00199 else if (Opcode >= 0xa2 && Opcode <= 0xaf)
00200 {
00201 sprintf (sz, "Opcode: reserved 0x%x.\n", Opcode);
00202 Trace (2, sz);
00203 pDataSrc->Skip(ReadMWord(pDataSrc));
00204 }
00205 else if ((Opcode >= 0xb0 && Opcode <= 0xcf) ||
00206 (Opcode >= 0x8000 && Opcode <= 0x80ff))
00207 {
00208
00209 sprintf (sz, "Opcode: reserved 0x%x.\n", Opcode);
00210 Trace (2, sz);
00211 }
00212 else if ((Opcode >= 0xd0 && Opcode <= 0xfe) ||
00213 (Opcode >= 8100 && Opcode <= 0xffff))
00214 {
00215 sprintf (sz, "Opcode: reserved 0x%x.\n", Opcode);
00216 Trace (2, sz);
00217 pDataSrc->Skip(ReadMLong(pDataSrc));
00218 }
00219 else if (Opcode >= 0x100 && Opcode <= 0x7fff)
00220 {
00221 sprintf (sz, "Opcode: reserved 0x%x.\n", Opcode);
00222 Trace (2, sz);
00223 pDataSrc->Skip((Opcode >> 7) & 255);
00224 }
00225 else
00226 {
00227 char sz[256];
00228 sprintf (sz, "Can't handle Opcode %x.\n", Opcode);
00229 raiseError (PL_ERRFORMAT_UNKNOWN, sz);
00230 }
00231 }
00232 }
00233
00234
00235 PLWORD PLPictDecoder::readOpcode
00236 ( int Version,
00237 PLDataSource * pDataSrc
00238 )
00239
00240
00241 {
00242 if (Version == 2)
00243 pDataSrc->AlignToWord();
00244
00245 if (Version == 1)
00246 return ReadByte (pDataSrc);
00247 else
00248 return ReadMWord (pDataSrc);
00249 }
00250
00251
00253
00254
00255 void PLPictDecoder::clip
00256 ( PLDataSource * pDataSrc
00257 )
00258
00259 {
00260 MacRect ClipRect;
00261
00262 PLWORD len = ReadMWord(pDataSrc);
00263
00264 if (len == 0x000a)
00265 {
00266 readRect(&ClipRect, pDataSrc);
00267 }
00268 else
00269 pDataSrc->Skip(len - 2);
00270 }
00271
00272 void PLPictDecoder::pixPat
00273 ( PLDataSource * pDataSrc
00274 )
00275
00276 {
00277 PLWORD PatType;
00278 PLWORD rowBytes;
00279 MacpixMap p;
00280 PLWORD NumColors;
00281
00282 PatType = ReadMWord(pDataSrc);
00283
00284 switch (PatType)
00285 {
00286 case 2:
00287 pDataSrc->Skip(8);
00288 pDataSrc->Skip(5);
00289 break;
00290 case 1:
00291 {
00292 pDataSrc->Skip(8);
00293 rowBytes = ReadMWord(pDataSrc);
00294 readRect(&p.Bounds, pDataSrc);
00295 readPixmap(&p, pDataSrc);
00296
00297 PLPixel32 CT[256];
00298 readColourTable(&NumColors, pDataSrc, CT);
00299 skipBits(&p.Bounds, rowBytes, p.pixelSize, pDataSrc);
00300 }
00301 break;
00302 default:
00303 raiseError (PL_ERRFORMAT_UNKNOWN,
00304 "Unknown pattern type in pixPat.");
00305 }
00306 }
00307
00308 void PLPictDecoder::skipPolyOrRegion
00309 ( PLDataSource * pDataSrc
00310 )
00311 {
00312 Trace (3, "Skipping polygon or region.\n");
00313 pDataSrc->Skip (ReadMWord (pDataSrc) - 2);
00314 }
00315
00316 void PLPictDecoder::bitsRect
00317 ( PLDataSource * pDataSrc,
00318 PLBmp * pBmp
00319 )
00320
00321 {
00322 PLWORD rowBytes;
00323
00324 rowBytes = ReadMWord(pDataSrc);
00325
00326 if (rowBytes & 0x8000)
00327 doPixmap(rowBytes, false, pBmp, pDataSrc);
00328 else
00329 doBitmap(rowBytes, false, pBmp, pDataSrc);
00330 }
00331
00332 void PLPictDecoder::bitsRegion
00333 ( PLDataSource * pDataSrc,
00334 PLBmp * pBmp
00335 )
00336
00337 {
00338 PLWORD rowBytes;
00339
00340 rowBytes = ReadMWord(pDataSrc);
00341
00342 if (rowBytes & 0x8000)
00343 doPixmap(rowBytes, true, pBmp, pDataSrc);
00344 else
00345 doBitmap(rowBytes, true, pBmp, pDataSrc);
00346 }
00347
00348 void PLPictDecoder::opcode9a
00349 ( PLDataSource * pDataSrc,
00350 PLBmp * pBmp
00351 )
00352
00353 {
00354 MacpixMap PixMap;
00355
00356 pDataSrc->Skip(4);
00357 ReadMWord(pDataSrc);
00358
00359
00360 readRect(&PixMap.Bounds, pDataSrc);
00361 readPixmap (&PixMap, pDataSrc);
00362
00363
00364 MacRect TempRect;
00365 readRect (&TempRect, pDataSrc);
00366 readRect (&TempRect, pDataSrc);
00367 PLWORD mode = ReadMWord(pDataSrc);
00368
00369
00370 createOutputBmp (PixMap, pBmp);
00371 pBmp->Lock(false, true);
00372
00373
00374 switch (PixMap.pixelSize)
00375 {
00376 case 32:
00377 unpack32bits (&PixMap.Bounds, 0, PixMap.cmpCount, pBmp, pDataSrc);
00378 break;
00379 case 8:
00380 unpack8bits (&PixMap.Bounds, 0, pBmp, pDataSrc);
00381 break;
00382 default:
00383 unpackbits (&PixMap.Bounds, 0, PixMap.pixelSize, pBmp, pDataSrc);
00384 }
00385 pBmp->Unlock();
00386 }
00387
00388 void PLPictDecoder::longComment
00389 ( PLDataSource * pDataSrc
00390 )
00391 {
00392 PLWORD type;
00393 PLWORD len;
00394
00395 type = ReadMWord(pDataSrc);
00396 len = ReadMWord(pDataSrc);
00397 if (len > 0)
00398 pDataSrc->Skip (len);
00399 }
00400
00401 void PLPictDecoder::headerOp
00402 ( PLDataSource * pDataSrc,
00403 PLBmp * pBmp
00404 )
00405 {
00406 int Version = ReadMWord (pDataSrc);
00407 m_Resolution.x = ReadMLong(pDataSrc);
00408 m_Resolution.y = ReadMLong(pDataSrc);
00409 MacRect Dummy;
00410 readRect (&Dummy, pDataSrc);
00411 ReadMWord (pDataSrc);
00412 }
00413
00414 void PLPictDecoder::jpegOp
00415 ( PLDataSource * pDataSrc,
00416 PLBmp * pBmp
00417 )
00418
00419 {
00420 long OpLen = ReadMLong(pDataSrc);
00421 bool bFound = false;
00422 int i = 0;
00423
00424
00425 while (!bFound && i < OpLen)
00426 {
00427 PLBYTE * pData = pDataSrc->GetBufferPtr (3);
00428 if (pData[0] == 0xFF && pData[1] == 0xD8 && pData[2] == 0xFF)
00429 bFound = true;
00430 else
00431 {
00432 ReadByte(pDataSrc);
00433 i++;
00434 }
00435 }
00436 if (bFound)
00437
00438 if (m_pJPEGDecoder)
00439 #ifdef PL_SUPPORT_JPEG
00440 m_pJPEGDecoder->MakeBmp (pDataSrc, pBmp);
00441 #else
00442 raiseError (PL_ERRFORMAT_NOT_SUPPORTED,
00443 "Library not compiled for PICT/JPEG.");
00444 #endif
00445 else
00446 raiseError (PL_ERRFORMAT_NOT_SUPPORTED,
00447 "Library not compiled for PICT/JPEG.");
00448 else
00449 raiseError (PL_ERRFORMAT_NOT_SUPPORTED,
00450 "PICT file contains unrecognized quicktime data.\n");
00451 }
00452
00454
00455
00456 void PLPictDecoder::createOutputBmp
00457 ( MacpixMap PixMap,
00458 PLBmp * pBmp
00459 )
00460 {
00461 int DestBPP;
00462 if (PixMap.pixelSize > 8)
00463 DestBPP = 32;
00464 else
00465 DestBPP = 8;
00466
00467 bool bAlpha = false;
00468
00469 if (DestBPP == 32 && PixMap.cmpCount == 4)
00470 bAlpha = true;
00471 pBmp->Create (PixMap.Bounds.right - PixMap.Bounds.left,
00472 PixMap.Bounds.bottom - PixMap.Bounds.top,
00473 DestBPP, bAlpha);
00474 }
00475
00476
00477 void PLPictDecoder::doBitmap
00478 ( int rowBytes,
00479 bool bIsRegion,
00480 PLBmp * pBmp,
00481 PLDataSource * pDataSrc
00482 )
00483
00484 {
00485 MacRect Bounds;
00486 MacRect SrcRect;
00487 MacRect DstRect;
00488 PLWORD mode;
00489 PLWORD width;
00490 PLWORD height;
00491
00492 Trace (2, "Reading version 1 bitmap.\n");
00493
00494 readRect(&Bounds, pDataSrc);
00495 dumpRect (" Bounds", &Bounds);
00496 readRect(&SrcRect, pDataSrc);
00497 readRect(&DstRect, pDataSrc);
00498
00499 width = Bounds.right - Bounds.left;
00500 height = Bounds.bottom - Bounds.top;
00501
00502
00503 pBmp->Create (width, height, 8, false);
00504
00505 mode = ReadMWord(pDataSrc);
00506
00507 if (bIsRegion)
00508 skipPolyOrRegion (pDataSrc);
00509
00510 pBmp->Lock(false, true);
00511 pBmp->SetPaletteEntry (0, 0, 0, 0, 255);
00512 pBmp->SetPaletteEntry (1, 255, 255, 255, 255);
00513 unpackbits (&Bounds, rowBytes, 1, pBmp, pDataSrc);
00514
00515 pBmp->Unlock();
00516 }
00517
00518 void PLPictDecoder::doPixmap
00519 ( int rowBytes,
00520 bool bIsRegion,
00521 PLBmp * pBmp,
00522 PLDataSource * pDataSrc
00523 )
00524
00525 {
00526 MacpixMap PixMap;
00527 PLWORD NumColors;
00528
00529 readRect(&PixMap.Bounds, pDataSrc);
00530 readPixmap(&PixMap, pDataSrc);
00531
00532 createOutputBmp (PixMap, pBmp);
00533
00534
00535 PLPixel32 Pal[256];
00536 readColourTable (&NumColors, pDataSrc, Pal);
00537 if (pBmp->GetBitsPerPixel() == 8)
00538 pBmp->SetPalette (Pal);
00539
00540
00541 MacRect TempRect;
00542 readRect (&TempRect, pDataSrc);
00543 readRect (&TempRect, pDataSrc);
00544 PLWORD mode = ReadMWord(pDataSrc);
00545
00546 if (bIsRegion)
00547 skipPolyOrRegion (pDataSrc);
00548
00549 pBmp->Lock(false, true);
00550 switch (PixMap.pixelSize)
00551 {
00552 case 32:
00553 unpack32bits (&PixMap.Bounds, rowBytes, PixMap.cmpCount, pBmp, pDataSrc);
00554 break;
00555 case 8:
00556 unpack8bits (&PixMap.Bounds, rowBytes, pBmp, pDataSrc);
00557 break;
00558 default:
00559 unpackbits (&PixMap.Bounds, rowBytes, PixMap.pixelSize,
00560 pBmp, pDataSrc);
00561 }
00562 pBmp->Unlock();
00563 }
00564
00565 void PLPictDecoder::unpack32bits
00566 ( MacRect* pBounds,
00567 PLWORD rowBytes,
00568 int NumBitPlanes,
00569 PLBmp * pBmp,
00570 PLDataSource * pDataSrc
00571 )
00572
00573
00574
00575
00576
00577 {
00578 int i,j;
00579 PLWORD BytesPerRow;
00580 PLPixel32 * pDestLine;
00581
00582 PLBYTE * pLinebuf;
00583
00584
00585 PLPixel32 ** pLineArray = pBmp->GetLineArray32();
00586
00587
00588 int Height = pBounds->bottom - pBounds->top;
00589 int Width = pBounds->right - pBounds->left;
00590
00591 BytesPerRow = Width*NumBitPlanes;
00592
00593 if (rowBytes == 0)
00594 rowBytes = Width*4;
00595
00596
00597 pLinebuf = new PLBYTE [BytesPerRow];
00598
00599 try
00600 {
00601 for (i = 0; i < Height; i++)
00602 {
00603 int linelen;
00604 if (rowBytes > 250)
00605 linelen = ReadMWord(pDataSrc);
00606 else
00607 linelen = ReadByte(pDataSrc);
00608
00609 PLBYTE * pBuf = unpackPictRow (pLinebuf, pDataSrc, Width, rowBytes, linelen);
00610
00611
00612
00613 pDestLine = pLineArray[i];
00614
00615 if (NumBitPlanes == 3)
00616 for (j = 0; j < Width; j++)
00617 {
00618 pDestLine->SetB (*(pBuf+Width*2));
00619 pDestLine->SetG (*(pBuf+Width));
00620 pDestLine->SetR (*pBuf);
00621 pDestLine->SetA (0xFF);
00622 pDestLine++;
00623 pBuf++;
00624 }
00625 else
00626 for (j = 0; j < Width; j++)
00627 {
00628 pDestLine->SetB (*(pBuf+Width*3));
00629 pDestLine->SetG (*(pBuf+Width*2));
00630 pDestLine->SetR (*(pBuf+Width));
00631 pDestLine->SetA (*pBuf);
00632 pDestLine++;
00633 pBuf++;
00634 }
00635 }
00636 }
00637 catch (PLTextException)
00638 {
00639 delete [] pLinebuf;
00640 throw;
00641 }
00642 catch(...)
00643 {
00644 delete [] pLinebuf;
00645 throw;
00646 }
00647 delete [] pLinebuf;
00648 }
00649
00650
00651 void PLPictDecoder::unpack8bits
00652 ( MacRect* pBounds,
00653 PLWORD rowBytes,
00654 PLBmp * pBmp,
00655 PLDataSource * pDataSrc
00656 )
00657
00658
00659
00660
00661
00662
00663 {
00664 int i;
00665 PLBYTE ** pLineArray = pBmp->GetLineArray();
00666
00667 int Height = pBounds->bottom - pBounds->top;
00668 int Width = pBounds->right - pBounds->left;
00669
00670
00671 rowBytes &= 0x7fff;
00672
00673 if (rowBytes == 0)
00674 rowBytes = Width;
00675
00676 PLBYTE * pLineBuf = new PLBYTE [rowBytes];
00677
00678 try
00679 {
00680 for (i = 0; i < Height; i++)
00681 {
00682 int linelen;
00683 if (rowBytes > 250)
00684 linelen = ReadMWord(pDataSrc);
00685 else
00686 linelen = ReadByte(pDataSrc);
00687 PLBYTE * pRawLine = unpackPictRow (pLineBuf, pDataSrc, Width, rowBytes, linelen);
00688 memcpy (pLineArray[i], pRawLine, Width);
00689 }
00690 }
00691 catch (PLTextException)
00692 {
00693 delete [] pLineBuf;
00694 throw;
00695 }
00696 delete [] pLineBuf;
00697 }
00698
00699
00700 void PLPictDecoder::unpackbits
00701 ( MacRect* pBounds,
00702 PLWORD rowBytes,
00703 int pixelSize,
00704 PLBmp * pBmp,
00705 PLDataSource * pDataSrc
00706 )
00707
00708
00709
00710
00711
00712 {
00713 PLBYTE * pSrcLine;
00714 int i,j,k;
00715 PLWORD pixwidth;
00716 int linelen;
00717 int pkpixsize;
00718 PLBYTE * pDestLine;
00719 PLBYTE FlagCounter;
00720 int len;
00721 int PixelPerRLEUnit=0;
00722 PLBYTE * pLineBuf=NULL;
00723 PLBYTE * pBuf;
00724 PLBYTE ** pLineArray = pBmp->GetLineArray();
00725
00726 int Height = pBounds->bottom - pBounds->top;
00727 int Width = pBounds->right - pBounds->left;
00728
00729
00730 if (pixelSize <= 8)
00731 rowBytes &= 0x7fff;
00732
00733 pixwidth = Width;
00734 pkpixsize = 1;
00735 if (pixelSize == 16)
00736 {
00737 pkpixsize = 2;
00738 pixwidth *= 2;
00739 }
00740
00741 if (rowBytes == 0)
00742 rowBytes = pixwidth;
00743
00744 try
00745 {
00746
00747
00748
00749 switch (pixelSize)
00750 {
00751 case 1:
00752 PixelPerRLEUnit = 8;
00753 pLineBuf = new PLBYTE [(rowBytes+1) * 32];
00754 break;
00755 case 2:
00756 PixelPerRLEUnit = 4;
00757 pLineBuf = new PLBYTE [(rowBytes+1) * 16];
00758 break;
00759 case 4:
00760 PixelPerRLEUnit = 2;
00761 pLineBuf = new PLBYTE [(rowBytes+1) * 8];
00762 break;
00763 case 8:
00764 PixelPerRLEUnit = 1;
00765 pLineBuf = new PLBYTE [rowBytes * 4];
00766 break;
00767 case 16:
00768 PixelPerRLEUnit = 1;
00769 pLineBuf = new PLBYTE [rowBytes * 2 + 4];
00770 break;
00771 default:
00772 char sz[256];
00773 sprintf (sz,
00774 "Illegal bpp value in unpackbits: %d\n",
00775 pixelSize);
00776 raiseError (PL_ERRFORMAT_UNKNOWN, sz);
00777 }
00778
00779 if (rowBytes < 8)
00780 {
00781 for (i = 0; i < Height; i++)
00782 {
00783 pDestLine = pLineArray[i];
00784 pSrcLine = pDataSrc->ReadNBytes (rowBytes);
00785 if (pixelSize == 16)
00786 expandBuf(pDestLine, pSrcLine, Width, pixelSize);
00787 else
00788 expandBuf8(pDestLine, pSrcLine, Width, pixelSize);
00789 }
00790 }
00791 else
00792 {
00793 for (i = 0; i < Height; i++)
00794 {
00795 if (rowBytes > 250)
00796 linelen = ReadMWord(pDataSrc);
00797 else
00798 linelen = ReadByte(pDataSrc);
00799
00800 pSrcLine = pDataSrc->ReadNBytes(linelen);
00801 pBuf = pLineBuf;
00802
00803
00804
00805 for (j = 0; j < linelen; )
00806 {
00807 FlagCounter = pSrcLine[j];
00808 if (FlagCounter & 0x80)
00809 {
00810 if (FlagCounter == 0x80)
00811
00812
00813 j++;
00814 else
00815 {
00816 len = ((FlagCounter ^ 255) & 255) + 2;
00817
00818
00819 if (pixelSize == 16)
00820 {
00821 expandBuf (pBuf, pSrcLine+j+1, 1, pixelSize);
00822 for (k = 1; k < len; k++)
00823 {
00824 memcpy (pBuf+(k*4*PixelPerRLEUnit), pBuf,
00825 4*PixelPerRLEUnit);
00826 }
00827 pBuf += len*4*PixelPerRLEUnit;
00828 }
00829 else
00830 {
00831 expandBuf8 (pBuf, pSrcLine+j+1, 1, pixelSize);
00832 for (k = 1; k < len; k++)
00833 {
00834 memcpy (pBuf+(k*PixelPerRLEUnit), pBuf,
00835 PixelPerRLEUnit);
00836 }
00837 pBuf += len*PixelPerRLEUnit;
00838 }
00839 j += 1 + pkpixsize;
00840 }
00841 }
00842 else
00843 {
00844 len = (FlagCounter & 255) + 1;
00845 if (pixelSize == 16)
00846 {
00847 expandBuf (pBuf, pSrcLine+j+1, len, pixelSize);
00848 pBuf += len*4*PixelPerRLEUnit;
00849 }
00850 else
00851 {
00852 expandBuf8 (pBuf, pSrcLine+j+1, len, pixelSize);
00853 pBuf += len*PixelPerRLEUnit;
00854 }
00855 j += len * pkpixsize + 1;
00856 }
00857 }
00858 pDestLine = pLineArray[i];
00859 if (pixelSize == 16)
00860 memcpy (pDestLine, pLineBuf, 4*Width);
00861 else
00862 memcpy (pDestLine, pLineBuf, Width);
00863 }
00864 }
00865 }
00866 catch (PLTextException)
00867 {
00868 delete [] pLineBuf;
00869 throw;
00870 }
00871
00872 delete [] pLineBuf;
00873 }
00874
00875 void PLPictDecoder::skipBits
00876 ( MacRect* pBounds,
00877 PLWORD rowBytes,
00878 int pixelSize,
00879 PLDataSource * pDataSrc
00880 )
00881
00882 {
00883 int i;
00884 PLWORD pixwidth;
00885 int linelen;
00886
00887 int Height = pBounds->bottom - pBounds->top;
00888 int Width = pBounds->right - pBounds->left;
00889
00890
00891 if (pixelSize <= 8)
00892 rowBytes &= 0x7fff;
00893
00894 pixwidth = Width;
00895
00896 if (pixelSize == 16)
00897 pixwidth *= 2;
00898
00899 if (rowBytes == 0)
00900 rowBytes = pixwidth;
00901
00902 if (rowBytes < 8)
00903 {
00904 pDataSrc->Skip (rowBytes*Height);
00905 }
00906 else
00907 {
00908 for (i = 0; i < Height; i++)
00909 {
00910 if (rowBytes > 250)
00911 linelen = ReadMWord(pDataSrc);
00912 else
00913 linelen = ReadByte(pDataSrc);
00914 pDataSrc->Skip (linelen);
00915 }
00916 }
00917 }
00918
00919
00920 void PLPictDecoder::expandBuf
00921 ( PLBYTE * pDestBuf,
00922 PLBYTE * pSrcBuf,
00923 int Width,
00924
00925 int bpp
00926 )
00927
00928 {
00929 PLBYTE * pSrc;
00930 PLBYTE * pDest;
00931 int i;
00932
00933 pSrc = pSrcBuf;
00934 pDest = pDestBuf;
00935
00936 switch (bpp)
00937 {
00938 case 16:
00939 for (i=0; i<Width; i++)
00940 {
00941 PLWORD Src = pSrcBuf[1]+(pSrcBuf[0]<<8);
00942 *(pDestBuf+PL_RGBA_BLUE) = ((Src) & 31)*8;
00943 *(pDestBuf+PL_RGBA_GREEN) = ((Src >> 5) & 31)*8;
00944 *(pDestBuf+PL_RGBA_RED) = ((Src >> 10) & 31)*8;
00945 *(pDestBuf+PL_RGBA_ALPHA) = 0xFF;
00946 pSrcBuf += 2;
00947 pDestBuf += 4;
00948 }
00949 break;
00950 default:
00951 raiseError (PL_ERRFORMAT_UNKNOWN,
00952 "Bad bits per pixel in expandBuf.");
00953 }
00954 return;
00955 }
00956
00957
00958 void PLPictDecoder::expandBuf8
00959 ( PLBYTE * pDestBuf,
00960 PLBYTE * pSrcBuf,
00961 int Width,
00962 int bpp
00963 )
00964
00965
00966 {
00967 PLBYTE * pSrc;
00968 PLBYTE * pDest;
00969 int i;
00970
00971 pSrc = pSrcBuf;
00972 pDest = pDestBuf;
00973
00974 switch (bpp)
00975 {
00976 case 8:
00977 memcpy (pDestBuf, pSrcBuf, Width);
00978 break;
00979 case 4:
00980 for (i=0; i<Width; i++)
00981 {
00982 *pDest = (*pSrc >> 4) & 15;
00983 *(pDest+1) = (*pSrc & 15);
00984 pSrc++;
00985 pDest += 2;
00986 }
00987 if (Width & 1)
00988 {
00989 *pDest = (*pSrc >> 4) & 15;
00990 pDest++;
00991 }
00992 break;
00993 case 2:
00994 for (i=0; i<Width; i++)
00995 {
00996 *pDest = (*pSrc >> 6) & 3;
00997 *(pDest+1) = (*pSrc >> 4) & 3;
00998 *(pDest+2) = (*pSrc >> 2) & 3;
00999 *(pDest+3) = (*pSrc & 3);
01000 pSrc++;
01001 pDest += 4;
01002 }
01003 if (Width & 3)
01004 for (i=6; i>8-(Width & 3)*2; i-=2)
01005 {
01006 *pDest = (*pSrc >> i) & 3;
01007 pDest++;
01008 }
01009 break;
01010 case 1:
01011 for (i=0; i<Width; i++)
01012 {
01013 *pDest = (*pSrc >> 7) & 1;
01014 *(pDest+1) = (*pSrc >> 6) & 1;
01015 *(pDest+2) = (*pSrc >> 5) & 1;
01016 *(pDest+3) = (*pSrc >> 4) & 1;
01017 *(pDest+4) = (*pSrc >> 3) & 1;
01018 *(pDest+5) = (*pSrc >> 2) & 1;
01019 *(pDest+6) = (*pSrc >> 1) & 1;
01020 *(pDest+7) = (*pSrc & 1);
01021 pSrc++;
01022 pDest += 8;
01023 }
01024 if (Width & 7)
01025 for (i=7; i>(8-Width & 7); i--)
01026 {
01027 *pDest = (*pSrc >> i) & 1;
01028 pDest++;
01029 }
01030 break;
01031 default:
01032 raiseError (PL_ERRFORMAT_UNKNOWN,
01033 "Bad bits per pixel in expandBuf8.");
01034 }
01035 return;
01036 }
01037
01038
01040
01041
01042 void PLPictDecoder::readPixmap
01043 ( MacpixMap * pPixMap,
01044 PLDataSource * pDataSrc
01045 )
01046 {
01047 pPixMap->version = ReadMWord(pDataSrc);
01048 pPixMap->packType = ReadMWord(pDataSrc);
01049 pPixMap->packSize = ReadMLong(pDataSrc);
01050 pPixMap->hRes = ReadMLong(pDataSrc);
01051 pPixMap->vRes = ReadMLong(pDataSrc);
01052 pPixMap->pixelType = ReadMWord(pDataSrc);
01053 pPixMap->pixelSize = ReadMWord(pDataSrc);
01054 pPixMap->cmpCount = ReadMWord(pDataSrc);
01055 pPixMap->cmpSize = ReadMWord(pDataSrc);
01056 pPixMap->planeBytes = ReadMLong(pDataSrc);
01057 pPixMap->pmTable = ReadMLong(pDataSrc);
01058 pPixMap->pmReserved = ReadMLong(pDataSrc);
01059
01060 tracePixMapHeader (2, pPixMap);
01061 }
01062
01063 void PLPictDecoder::readColourTable
01064 ( PLWORD * pNumColors,
01065 PLDataSource * pDataSrc,
01066 PLPixel32 * pPal
01067 )
01068
01069 {
01070 PLLONG ctSeed;
01071 PLWORD ctFlags;
01072 PLWORD val;
01073 int i;
01074
01075 Trace (3, "Getting color table info.\n");
01076
01077 ctSeed = ReadMLong(pDataSrc);
01078 ctFlags = ReadMWord(pDataSrc);
01079 *pNumColors = ReadMWord(pDataSrc)+1;
01080
01081 char sz[256];
01082 sprintf (sz, "Palette Size: %d\n", *pNumColors);
01083 Trace (2, sz);
01084 Trace (3, "Reading Palette.\n");
01085
01086 for (i = 0; i < *pNumColors; i++)
01087 {
01088 val = ReadMWord(pDataSrc);
01089 if (ctFlags & 0x8000)
01090
01091
01092
01093 val = i;
01094 if (val >= *pNumColors)
01095 {
01096 raiseError (PL_ERRFORMAT_UNKNOWN,
01097 "pixel value greater than colour table size.");
01098 }
01099
01100 pPal[val].SetR ((PLBYTE) (((PLWORD) (ReadMWord(pDataSrc)) >> 8) & 0xFF));
01101 pPal[val].SetG ((PLBYTE) (((PLWORD) (ReadMWord(pDataSrc)) >> 8) & 0xFF));
01102 pPal[val].SetB ((PLBYTE) (((PLWORD) (ReadMWord(pDataSrc)) >> 8) & 0xFF));
01103 }
01104
01105 }
01106
01107 void PLPictDecoder::readRect
01108 ( MacRect * pr,
01109 PLDataSource * pDataSrc
01110 )
01111 {
01112 pr->top = ReadMWord(pDataSrc);
01113 pr->left = ReadMWord(pDataSrc);
01114 pr->bottom = ReadMWord(pDataSrc);
01115 pr->right = ReadMWord(pDataSrc);
01116 }
01117
01118
01119 void PLPictDecoder::dumpRect
01120 ( char * psz,
01121 MacRect * pr
01122 )
01123 {
01124 char sz[256];
01125 sprintf (sz, "%s (%d,%d) (%d,%d).\n",
01126 psz, pr->left, pr->top, pr->right, pr->bottom);
01127 Trace (2, sz);
01128 }
01129
01130
01131 void PLPictDecoder::tracePixMapHeader
01132 ( int Level,
01133 MacpixMap * pPixMap
01134 )
01135 {
01136 char sz[256];
01137 Trace (Level, "PixMap header info:\n");
01138 dumpRect (" Bounds:", &(pPixMap->Bounds));
01139
01140 sprintf (sz, " version: 0x%x\n", pPixMap->version);
01141 Trace (Level, sz);
01142 sprintf (sz, " packType: %d\n", pPixMap->packType);
01143 Trace (Level, sz);
01144 sprintf (sz, " packSize: %ld\n", pPixMap->packSize);
01145 Trace (Level, sz);
01146 sprintf (sz, " pixelSize: %d\n", pPixMap->pixelSize);
01147 Trace (Level, sz);
01148 sprintf (sz, " cmpCount: %d\n", pPixMap->cmpCount);
01149 Trace (Level, sz);
01150 sprintf (sz, " cmpSize: %d.\n", pPixMap->cmpSize);
01151 Trace (Level, sz);
01152 sprintf (sz, " planeBytes: %ld.\n", pPixMap->planeBytes);
01153 Trace (Level, sz);
01154 }
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219