#include <ai_bmp.h>
Public Member Functions | |
AIBitmapProcessor () | |
virtual | ~AIBitmapProcessor () |
BOOL | BeginRaster () |
Allows the bitmap process to intialize itself for a new bitmap signalled by the BeginRaster comment. | |
BOOL | DecodeXI (AI5EPSFilter &filter) |
Decodes the EPS XI, bitmap definition in an Illustrator 5 file. | |
BOOL | EndRaster () |
Allows the bitmap processor to complete the bitmap signalled by the EndRaster comment. | |
Protected Member Functions | |
BOOL | ReadImageData (AI5EPSFilter &filter, const INT32 ImageType, ADDR pDataStart, INT32 nLength, INT32 nLineLength, INT32 nMaxLineOffset) |
Decodes the hex string style data following an image (XI) operator placing it in the given buffer. This allows the bitmap data to be read into a bitmap. | |
INT32 | DecodeHexStringAsCMYK (AI5EPSFilter &filter, ADDR &pCurrentLine, INT32 &nLineOffset, INT32 nLineLength, INT32 nMaxLineOffset, UINT32 nStart, BYTE CMYKval[], UINT32 &nShift) |
Treat the current token as a hex string, and decode it into a BGR bitmap. | |
INT32 | DecodeHexStringAsRGB (AI5EPSFilter &filter, ADDR &pCurrentLine, INT32 &nLineOffset, INT32 nLineLength, INT32 nMaxLineOffset, UINT32 nStart, BYTE RGBval[], UINT32 &nShift) |
Treat the current token as a hex string, and decode it into a BGR bitmap. | |
Private Attributes | |
KernelBitmap * | mpNewBitmap |
ImportedBitmaps | mBitmaps |
INT32 | mLastIndex |
Definition at line 124 of file ai_bmp.h.
|
Definition at line 123 of file ai_bmp.cpp. 00123 : 00124 mpNewBitmap(0), 00125 mLastIndex(0) 00126 { 00127 00128 }
|
|
Definition at line 130 of file ai_bmp.cpp. 00131 { 00132 delete mpNewBitmap; 00133 mpNewBitmap = 0; 00134 }
|
|
Allows the bitmap process to intialize itself for a new bitmap signalled by the BeginRaster comment.
Definition at line 150 of file ai_bmp.cpp. 00151 { 00152 ENSURE(mpNewBitmap == NULL, "mpNewBitmap is not NULL"); 00153 00154 return TRUE; 00155 }
|
|
Treat the current token as a hex string, and decode it into a BGR bitmap.
Definition at line 592 of file ai_bmp.cpp. 00593 { 00594 UINT32 nTokenLen = camStrlen(filter.GetTokenBuf() + nStart); 00595 00596 // Assume hex strings are even-numbered in length for the moment 00597 if ( (nTokenLen & 1) != 0 ) 00598 { 00599 TRACE( _T("Bad hex string length in DecodeHexString\n") ); 00600 return -1; 00601 } 00602 00604 // Decode the string two characters at a time keeping a running CMYK value 00606 00607 double dRed, dGreen, dBlue; 00608 double dKey; 00609 00610 UINT32 i; 00611 for ( i = nStart; i < nTokenLen; i += 2 ) 00612 { 00614 // read in the CMYK value one component at at time 00615 // first clear the next value 00617 CMYKval[nShift] = 0; 00618 00619 if ( !CharToHex( filter.GetTokenBuf()[i], CMYKval[nShift] ) ) 00620 return -1; 00621 00622 CMYKval[nShift] <<= 4; 00623 00624 if ( !CharToHex( filter.GetTokenBuf()[i + 1], CMYKval[nShift] ) ) 00625 return -1; 00626 00627 ++nShift; 00628 00630 // once we have a complete CMYK value, stick it in the bitmap 00632 if ( nShift > 3 ) 00633 { 00635 // Convert the colour into an RGB format. 00637 00638 dKey = double(CMYKval[3]) / 255.0; 00639 00640 dRed = 1.0 - (min(1.0, (double(CMYKval[0]) / 255.0 + dKey ))); 00641 dGreen = 1.0 - (min(1.0, (double(CMYKval[1]) / 255.0 + dKey ))); 00642 dBlue = 1.0 - (min(1.0, (double(CMYKval[2]) / 255.0 + dKey ))); 00643 00645 // Set the value for the current pixel in the bitmap. 00647 00648 pCurrentLine[nLineOffset++] = ColourValueToByte( dBlue ); 00649 pCurrentLine[nLineOffset++] = ColourValueToByte( dGreen ); 00650 pCurrentLine[nLineOffset++] = ColourValueToByte( dRed ); 00651 00652 if ( nLineOffset > nMaxLineOffset ) 00653 { 00654 pCurrentLine -= nLineLength; 00655 nLineOffset = 0; 00656 } 00657 00659 // start the next CMYK value 00661 00662 nShift = 0; 00663 } 00664 } 00665 00666 // How much data did we read? 00667 return i; 00668 }
|
|
Treat the current token as a hex string, and decode it into a BGR bitmap.
Definition at line 700 of file ai_bmp.cpp. 00701 { 00702 UINT32 nTokenLen = camStrlen(filter.GetTokenBuf() + nStart); 00703 00704 // Assume hex strings are even-numbered in length for the moment 00705 if ( (nTokenLen & 1) != 0 ) 00706 { 00707 TRACE( _T("Bad hex string length in DecodeHexString\n") ); 00708 return -1; 00709 } 00710 00712 // Decode the string two characters at a time 00714 00715 UINT32 i; 00716 for ( i = nStart; i < nTokenLen; i += 2 ) 00717 { 00718 RGBVal[nShift] = 0; 00719 00720 if ( !CharToHex( filter.GetTokenBuf()[i], RGBVal[nShift] ) ) 00721 return -1; 00722 00723 RGBVal[nShift] <<= 4; 00724 00725 if ( !CharToHex( filter.GetTokenBuf()[i + 1], RGBVal[nShift] ) ) 00726 return -1; 00727 00728 ++nShift; 00729 00731 // once we have a complete RGB value, stick it in the bitmap 00732 // reversing it to BGR 00734 00735 if ( nShift > 2 ) 00736 { 00737 pCurrentLine[nLineOffset++] = RGBVal[2]; 00738 pCurrentLine[nLineOffset++] = RGBVal[1]; 00739 pCurrentLine[nLineOffset++] = RGBVal[0]; 00740 00741 if ( nLineOffset > nMaxLineOffset ) 00742 { 00743 pCurrentLine -= nLineLength; 00744 nLineOffset = 0; 00745 } 00746 00747 nShift = 0; 00748 } 00749 } 00750 00751 // How much data did we read? 00752 return i; 00753 }
|
|
Decodes the EPS XI, bitmap definition in an Illustrator 5 file.
[ a b c d tx ty ] llx lly urx ury h w bits ImageType AlphaChannelCount reserved bin-ascii ImageMask XI Definition at line 173 of file ai_bmp.cpp. 00174 { 00175 // Graeme (18/4/00) - This code isn't very pretty, but it's necessary because of the way 00176 // in which the bitmap is stored. If I try a GetCoordPair () to get the bitmap positions, 00177 // the image will be misrendered because the transformation should take place due to the 00178 // tx and ty components of the matrix. Note also that the bitmap's position in Adobe 00179 // Illustrator is taken from the top left corner, whilst we use the bottom left. 00180 00182 // Get the page origin. 00184 00185 // Graeme (18/4/00) - Declare variables to get the origin of the page within Camelot's 00186 // co-ordinate space. 00187 Document *pDocument = filter.GetDocument (); 00188 Spread *pSpread = pDocument->FindFirstSpread (); 00189 Page *pPage = pSpread->FindFirstPageInSpread (); 00190 DocCoord Origin = pPage->GetPageRect ().lo; 00191 00193 // decode the bitmap parameters 00195 00196 Matrix ImageMatrix; 00197 DocCoord Translation; 00198 00199 INT32 h, w, bits, ImageType, AlphaChannelCount, reserved, bin_ascii, ImageMask; 00200 INT32 llx, lly, urx, ury; 00201 00202 INT32 nLength = 0; 00203 INT32 nLineLength = 0; 00204 INT32 nMaxLineOffset = 0; 00205 00206 INT32 nChannels = 0; 00207 00208 NodeBitmap* pNodeBitmap = NULL; 00209 DocCoord p; 00210 00211 // Graeme (18/4/00) - I've replaced the Pop with PopCoordPair for extracting the 00212 // bounding co-ordinates of the bitmap. This means that they will be scaled up 00213 // into the Xara co-ordinate space. I've also reversed the popping of h and w 00214 // from the stack - their order is incorrect in the AI documentation. 00215 if ( !filter.GetStack().Pop(&ImageMask) || 00216 !filter.GetStack().Pop(&bin_ascii) || 00217 !filter.GetStack().Pop(&reserved) || 00218 !filter.GetStack().Pop(&AlphaChannelCount) || 00219 !filter.GetStack().Pop(&ImageType) || 00220 !filter.GetStack().Pop(&bits) || 00221 !filter.GetStack().Pop(&h) || 00222 !filter.GetStack().Pop(&w) || 00223 !filter.GetStack().PopCoord(&ury) || 00224 !filter.GetStack().PopCoord(&urx) || 00225 !filter.GetStack().PopCoord(&lly) || 00226 !filter.GetStack().PopCoord(&llx) || 00227 !filter.GetStack().Pop( &ImageMatrix, TRUE ) 00228 ) 00229 goto EPSError; 00230 00232 // create space for the tentative bitmap 00234 00236 // ImageType gives the number of channels per pixel 00237 // bits is the bits per channel 00238 // However we will convert CMYK bitmaps to RGB 00240 00241 switch ( ImageType ) 00242 { 00243 case 1: // greyscale 00244 nChannels = 1; 00245 break; 00246 case 3: // rgb 00247 nChannels = 3; 00248 break; 00249 case 4: // CMYK 00250 nChannels = 3; 00251 break; 00252 default: // unknown 00253 goto EPSError; 00254 } 00255 00256 mpNewBitmap = new KernelBitmap( w, h, bits * nChannels, 96 ); 00257 if ( !mpNewBitmap ) 00258 goto EPSError; 00259 00261 // We can import greyscale bitmaps as well 00263 00264 if ( ImageType == 1 ) 00265 mpNewBitmap->SetAsGreyscale(); 00266 00267 00269 // get the binary data 00271 00272 nLength = mpNewBitmap->GetActualBitmap()->GetBitmapSize(); 00273 nLineLength = mpNewBitmap->GetActualBitmap()->GetScanlineSize(); 00274 nMaxLineOffset = (( w * mpNewBitmap->GetActualBitmap()->GetBPP() ) / 8) - 1; 00275 00276 if ( !ReadImageData( filter, ImageType, mpNewBitmap->GetBitmapBits(), nLength, nLineLength, nMaxLineOffset ) ) 00277 goto EPSError; 00278 00280 // insert the image into the document 00282 00283 // Get a new NodeBitmap object to import into. Don't know what the 12,12 bit does 00284 pNodeBitmap = new NodeBitmap; 00285 00286 if ( !pNodeBitmap || !pNodeBitmap->SetUpPath(12,12) ) 00287 goto EPSError; 00288 00289 pNodeBitmap->GetBitmapRef()->Attach( mpNewBitmap, filter.GetDocument() ); 00290 00292 // set up the bounds of the shape containing the bitmap 00294 00295 // Graeme (18/4/00) - Adjust the values of lly and ury before they're transformed. 00296 lly -= h * EPSScaleFactor; 00297 ury -= h * EPSScaleFactor; 00298 00299 // Graeme (18/4/00) - Modify the matrix to place the bitmap in the correct place. 00300 ImageMatrix.GetTranslation ( Translation ); // Extract the translation component. 00301 Translation += Origin; // Add the page origin to it. 00302 ImageMatrix.SetTranslation ( Translation ); // And reset the value in the matrix. 00303 00304 // Graeme (17/4/00) - Colin overlooked setting up the bounding parallelogram when he 00305 // wrote this code, and I've just added this. 00306 p.x = llx; 00307 p.y = ury; 00308 ImageMatrix.transform( &p ); 00309 pNodeBitmap->InkPath.InsertMoveTo( p ); 00310 pNodeBitmap->Parallel [0] = p; 00311 00312 p.x = urx; 00313 p.y = ury; 00314 ImageMatrix.transform( &p ); 00315 pNodeBitmap->InkPath.InsertLineTo( p ); 00316 pNodeBitmap->Parallel [1] = p; 00317 00318 p.x = urx; 00319 p.y = lly; 00320 ImageMatrix.transform( &p ); 00321 pNodeBitmap->InkPath.InsertLineTo( p ); 00322 pNodeBitmap->Parallel [2] = p; 00323 00324 p.x = llx; 00325 p.y = lly; 00326 ImageMatrix.transform( &p ); 00327 pNodeBitmap->InkPath.InsertLineTo( p ); 00328 pNodeBitmap->Parallel [3] = p; 00329 00330 p.x = llx; 00331 p.y = ury; 00332 ImageMatrix.transform( &p ); 00333 pNodeBitmap->InkPath.InsertLineTo( p ); 00334 00335 pNodeBitmap->InkPath.CloseSubPath(); 00336 00337 // Graeme (18/4/00) - It is necessary to set the default attributes up for a 00338 // new node bitmap before inserting it into the tree. Otherwise it's rendered 00339 // as a greyscale image, even if it is colour, because there's a start colour 00340 // value set. 00341 pNodeBitmap->ApplyDefaultBitmapAttrs ( NULL ); 00342 00343 filter.AddNewNode( pNodeBitmap ); 00344 00345 return TRUE; 00346 00347 EPSError: 00348 if ( mpNewBitmap ) 00349 { 00350 delete mpNewBitmap; 00351 mpNewBitmap = 0; 00352 } 00353 00354 return FALSE; 00355 }
|
|
Allows the bitmap processor to complete the bitmap signalled by the EndRaster comment.
Definition at line 371 of file ai_bmp.cpp. 00372 { 00373 ENSURE(mpNewBitmap != NULL, "mpNewBitmap is NULL"); 00374 00376 // add bitmap to tentative bitmap list, giving an index number 00378 00379 mBitmaps.AddBitmap( mpNewBitmap, mLastIndex ); 00380 00381 // up the index number 00382 ++mLastIndex; 00383 00384 // We're done with this bitmap. 00385 mpNewBitmap = NULL; 00386 00387 return TRUE; 00388 }
|
|
Decodes the hex string style data following an image (XI) operator placing it in the given buffer. This allows the bitmap data to be read into a bitmap.
Assumes that the first % token has not yet been read. Definition at line 420 of file ai_bmp.cpp. 00421 { 00423 // ignore the whitespace (EOL) 00425 00426 filter.GetEPSFile()->GetToken(); 00427 00429 // read the first % line 00431 filter.GetEPSFile()->GetToken(); 00432 00434 // We need some running values 00436 BYTE ColourVal[4] = {0,0,0,0}; 00437 UINT32 nShift = 0; // which colour component is being read 00438 00440 // start with last line 00442 00443 ADDR pCurrentLine = pDataStart + nLength - nLineLength; 00444 INT32 nLineOffset = 0; 00445 00446 while ( pCurrentLine >= pDataStart && !filter.GetEPSFile()->eof() ) 00447 { 00448 // the data ends with a comment 00449 if ( camStrncmp( filter.GetTokenBuf(), _T("%%EndData"), 9 ) == 0 ) 00450 break; 00451 00453 // update progress 00455 const INT32 nCharsRead = filter.GetEPSFile()->GetCharsRead(); 00456 if ( nCharsRead > (filter.GetLastProgressUpdate() + 2048) ) 00457 { 00458 if ( !ContinueSlowJob( nCharsRead ) ) 00459 { 00460 // Abort operation - make sure nodes are deleted and not added to the tree. 00461 ERROR(_R(IDT_IMPORT_USERABORT), FALSE); 00462 } 00463 else 00464 { 00465 filter.GetLastProgressUpdate() = nCharsRead; 00466 } 00467 } 00468 00470 // Decode the token into hex data (starting after the %) 00472 00473 INT32 nBytes = 0; 00474 00475 switch ( ImageType ) 00476 { 00477 case 1: // greyscale 00478 nBytes = filter.DecodeHexString( pCurrentLine, nLength, 1 ); 00479 break; 00480 00481 case 3: // rgb 00482 nBytes = DecodeHexStringAsRGB( filter, pCurrentLine, nLineOffset, nLineLength, nMaxLineOffset, 1, ColourVal, nShift ); 00483 break; 00484 00485 case 4: // CMYK 00486 nBytes = DecodeHexStringAsCMYK( filter, pCurrentLine, nLineOffset, nLineLength, nMaxLineOffset, 1, ColourVal, nShift ); 00487 break; 00488 } 00489 00490 if ( nBytes == -1 ) 00491 { 00492 // Error 00493 TRACE( _T("Error in AI5 image data\n") ); 00494 break; 00495 } 00496 00498 // get the next token 00500 filter.GetEPSFile()->GetToken(); 00501 } 00502 00503 return ( pDataStart - pCurrentLine == nLineLength ) ? TRUE : FALSE; 00504 }
|
|
|
|
|
|
|