void PNGProgressBar::UpdateCallback(png_structp png_ptr, png_uint_32 row_number, INT32 pass) { if (show_progress_bar) { if (interlaced) // Interlaced image { if (pass + 1 >= next_update) ContinueSlowJob(pass + 1); } else // Non-interlaced image { if ((INT32)row_number >= next_update) ContinueSlowJob(row_number); } } }
INT32 LibraryFile::Init(SuperGallery *ParentGal, PathName *APath, SGLibType Type, BOOL Updated, BOOL DoScroll) { #ifndef EXCLUDE_GALS if(ParentGal == NULL || APath == NULL || !Libraries.IsEmpty()) { ERROR3("LibraryFile::Init - NULL parameters are illegal OR Init called > 1 times"); if(!Libraries.IsEmpty()) return(Libraries.GetCount()); else return 0; } BOOL ok = TRUE; // Tidy up Path a bit String_256 OurPath(APath->GetPath()); LibraryFile::TidyUpSubPath(&OurPath); // Now point Path to the new pathname PathName ModifiedPath(OurPath); PathName *Path = &ModifiedPath; if(!ModifiedPath.IsValid()) { ERROR3("LibraryFile::Init -> Modified library path is invalid"); return 0; } // Remember the pathname and type MyPath = *Path; MyType = Type; ParentGallery = ParentGal; if(ParentGallery->IsKindOf(CC_RUNTIME_CLASS(LibraryGallery))) ParentLibraryGallery = (LibraryGallery *)ParentGal; else { ERROR3("LibraryFile::Init passed a non-library gallery - yikes..."); return 0; } // Need to reset the Quiet status before a stream of Library::Init calls ParentLibraryGallery->SetQuietStatus(FALSE); BOOL Retry = TRUE; while(Retry) { Retry = FALSE; // Would be nice to have a way of adding a file to a path in PathName... Is there one ? if(!SGLibOil::FileExists(Path)) { // We're opening the font gallery, but can't find the font library path - don't warn if(Type == SGLib_Font) return 0; // tell the user that the directory doesn't exist String_256 WarnMsg; String_256 DefaultIndex; String_256 IndexDesc; BOOL CanGenerate; ok = LibraryFile::GetSubIndexDetails(ParentLibraryGallery, &DefaultIndex, &IndexDesc, &CanGenerate); String_256 TmpPath(Path->GetLocation(FALSE)); LibraryFile::TidyUpSubPath(&TmpPath); // Taken out by Graham 30/10/97: If the gallery had no directory specified, //we used to throw a warning which said "do you want to specify another folder?" //We don't do this any more, because the default is to open all galleries empty and //then download stuff from the Xara web site #if 0 WarnMsg.MakeMsg(_R(IDS_BROWSE_OR_SCAN), (TCHAR *)IndexDesc, (TCHAR *)TmpPath); Error::SetError(0, WarnMsg, 0); INT32 ButtonPressed = InformWarning(0, _R(IDS_BROWSE), _R(IDS_RETRY), _R(IDS_CANCEL)/*, _R(IDS_HELP)*/); #else // WEBSTER INT32 ButtonPressed = 3; #endif // WEBSTER TRACEUSER( "Richard", _T("ButtonPressed: %d\n"), ButtonPressed); Error::ClearError(); switch(ButtonPressed) { case 1: { // Open the Browse dialog (or the Add.. dialog as it seems to be called now) PathName ThePath(*Path); // This returns FALSE if Cancel was hit, or an error occurred. if(!SGLibOil::GetLibPath(ParentLibraryGallery, &ThePath, CanGenerate, Type)) { ERROR3("GetLibPath returned FALSE in LF::Init"); return 0; } else { ModifiedPath = ThePath; if(!ModifiedPath.IsValid()) { ERROR3("LibraryFile::Init -> scanned library path is invalid"); return 0; } // Remember the pathname MyPath = ThePath; switch(Type) { case SGLib_ClipArt: case SGLib_Bitmap: LibClipartSGallery::DefaultLibraryPath = MyPath.GetPath(); LibClipartSGallery::ClipartPath = LibClipartSGallery::DefaultLibraryPath; break; case SGLib_ClipArt_WebThemes: LibClipartSGallery::DefaultLibraryPath = MyPath.GetPath(); LibClipartSGallery::WebThemePath = LibClipartSGallery::DefaultLibraryPath; break; #ifndef STANDALONE case SGLib_Texture: case SGLib_Fractal: LibFillsSGallery::DefaultLibraryPath = MyPath.GetPath(); break; case SGLib_Font: // WEBSTER-Martin-09/01/97 - Put back by Ranbir. //#ifndef WEBSTER FontsSGallery::DefaultLibraryPath = MyPath.GetPath(); break; // Not in webster so we get the error below //#endif // WEBSTER #endif default: ERROR2(FALSE,"Library::ScanForLocation Type not present!"); break; } } break; } case 2: Retry = TRUE; #if 0 { // Scan String_256 Result; if(!Library::ScanForLocation(Type, &Result)) { ERROR3("No libraries found..."); return 0; } if(!ModifiedPath.SetPathName(Result)) { ERROR3("LibraryFile::Init -> scanned library path is invalid"); return 0; } // Remember the pathname and type MyPath = *Path; } #endif break; case 3: // Cancel return 0; } } } // Wipe libraries added to gallery for scroll / redraw purposes... InitScrollRedrawSystem(); // Check the actual path exists if(SGLibOil::FileExists(Path)) { // Would be nice to have a way of adding a file to a path in PathName... Is there one ? String_256 IndexFile((const TCHAR *)Path->GetPath(TRUE)); // "%s\\XaraInfo\\index.txt" IndexFile += String_16(_R(IDS_LIBRARIES_XARAINFO_DIRNAME)); IndexFile += TEXT("\\") + String_16(_R(IDS_LIBRARIES_INDEX_FILENAME)); PathName IndexFilePath(IndexFile); if(!IndexFilePath.IsValid()) { ERROR3("LibraryFile::Init indexfilepath is invalid"); return 0; } CCDiskFile MainIndex; if (!MainIndex.InitLexer(FALSE)) { // SetError! ERROR3("LibraryFile::LibraryFile InitLexer failed"); return(0); } if(SGLibOil::FileExists(&IndexFilePath)) { // Count lines in index file INT32 Count = CountLines(&IndexFilePath); TRACEUSER( "Richard", _T("%d lines in index file\n"), Count); // Used for the percentage display INT32 CurrentGroupNumber = 0; // Just in case there's a slow job already going on... SmashSlowJob(); String_64 SlowJob(_R(IDS_LIBRARY_SCANNING)); BeginSlowJob(Count, FALSE, &SlowJob); // Now use the index file to create each group in turn if (MainIndex.open(IndexFilePath, ios::in)) { MainIndex.SetWhitespace(""); // Setting this to blank lets us read non-"'d strings MainIndex.SetDelimiters(","); // ,s delimit our fields MainIndex.SetCommentMarker('#'); // #'d lines are commented out MainIndex.SetStringDelimiters(""); // No string delimiters String_64 Directory; String_64 Description; String_64 SubIndex; String_64 Kind; LexTokenType TT; BOOL EscapePressed = FALSE; while(ok && !EscapePressed) { if(!MainIndex.GetToken()) break; // Get SubLib directory name // Keep reading tokens until we hit a normal one... (skips line ends and // comments for us TT = MainIndex.GetTokenType(); while (TT != TOKEN_NORMAL && ok) { ok = MainIndex.GetToken(); if(!ok) break; TT = MainIndex.GetTokenType(); ok = (TT != TOKEN_EOF); if(!ok) break; } if(!ok) break; Directory = MainIndex.GetTokenBuf(); KillLeadingSpaces(&Directory); if(!MainIndex.GetToken()) break; // Get ',' if(!MainIndex.GetToken()) break; // Get Description String_256 Description256; Description256 = MainIndex.GetTokenBuf(); KillLeadingSpaces(&Description256); Description256.Left(&Description, 60); if(!MainIndex.GetToken()) break; // Get ',' if(!MainIndex.GetToken()) break; // Get Sub Library Index name SubIndex = MainIndex.GetTokenBuf(); KillLeadingSpaces(&SubIndex); if(!MainIndex.GetToken()) break; // Get ',' if(!MainIndex.GetToken()) break; // Get type of files in sublib Kind = MainIndex.GetTokenBuf(); KillLeadingSpaces(&Kind); BOOL Match = FALSE; Match = ParentLibraryGallery->CheckForIndexMatch(&Kind); if(Match) { // Show status of additions EscapePressed = !ContinueSlowJob(CurrentGroupNumber++); // Sort pathname of sublib directory out String_256 SubP(Path->GetPath(TRUE)); SubP += Directory; PathName SubPath(SubP); if(!SubPath.IsValid()) { ERROR3("LibraryFile::Init - invalid subpath"); if(MainIndex.isOpen()) MainIndex.close(); EndSlowJob(); return 0; } // Go ahead and add the new group if(ok) { // Create the sub lib Library *NewSubLib = new Library; if (NewSubLib != NULL) { // Create the new group in the gallery (note the TRUE for create a virtualised one if // we can to save time / memory) if(NewSubLib->Init(ParentGal, &SubPath, &Description, &SubIndex, Type, Updated, TRUE)) { Libraries.AddTail(NewSubLib); // Keep track of libraries added for redraw purposes... AddNewFolderToScrollRedrawSystem(NewSubLib); } else { // This check is new, should be ok... delete NewSubLib; NewSubLib = NULL; ERROR3("Library::Init failed in LibraryFile::Init"); ok = FALSE; } } } } } } else { // Failed to open the index file... // SetError?! ERROR3("LibraryFile::LibraryFile couldn't open index file"); ok = FALSE; } EndSlowJob(); } else { // The directory given had no XaraInfo\index.txt file, maybe it's a sublib, check // For defaults... ok = CheckForSubIndexes(ParentGal, Path, Type, Updated); } // reclaim lexer-buffer memory MainIndex.DeinitLexer(); // And close the file if(MainIndex.isOpen()) MainIndex.close(); // Scroll / redraw the newly added groups... if(DoScroll) DoScrollRedraw(); } else { TRACEUSER( "Richard", _T("Path doesn't exist\n")); } // And return the number of items created return(Libraries.GetCount()); #endif return 0; }
BOOL DocumentFontDropDown::FillInFontList(Document * WorkDoc) { ERROR2IF(ParentDlg == NULL, FALSE, "FontDropDown not properly initialised"); BeginSlowJob(); SetListRedraw(FALSE); // Disable redraw while updating KillList(); // Delete combobox contents and empty the fonts list //ClearList(); // Delete combobox contents // Setup the static class pointer variable so we can add things to this dropdown... CurrentFontDropDown = (void *)this; //if(Fonts.GetCount() == 0) //{ if (WorkDoc == NULL) { // Fill in one item in the list which is no document fonts being used String_8 DashString(_R(IDS_K_FINFODLG_DASH)); TheTopItem.FontName = DashString; TheTopItem.Type = FC_UNDEFINED; //AddFontToList((TCHAR*)&TheTopItem.FontName, TheTopItem.Type); } else { // Build the font list for the specified document // This will NOT be alphabetical FontList DocFonts; DocFonts.Build(WorkDoc); FontListItem* FontItem = DocFonts.GetFirstItem(); if (FontItem == NULL) { // Fill in one item in the list which is no document fonts being used TheTopItem.FontName = _R(IDS_NO_FONTSINDOC); TheTopItem.Type = FC_UNDEFINED; //AddFontToList((TCHAR*)&TheTopItem.FontName, TheTopItem.Type); } else { //BOOL FirstInList = TRUE; // fill up the list while (FontItem != NULL) { // get the name String_64 Name = FontItem->GetFontName(); WORD Handle = FONTMANAGER->GetFontHandle(&Name); // check the style INT32 Style = FontItem->GetFontStyle(); if(Style & 1) Name += _T(" -Bold"); if(Style & 2) Name += _T(" -Italic"); if(Handle > 0) { if (FONTMANAGER->IsFontReplaced(Handle)) Name += _T(" *"); } FontClass Type = FontItem->GetFontClass(); AddFontToList(Name, Type); FontItem = DocFonts.GetNextItem(FontItem); ContinueSlowJob(); } } } //} // Work out the top item, if any, on the alphabetically sorted list // ready for putting in the top combo box item FontDropItem *pTopItem = (FontDropItem *)Fonts.GetHead(); if (pTopItem != NULL) { // Fill in the top item in the list TheTopItem.FontName = pTopItem->FontName; TheTopItem.Type = pTopItem->Type; } ListItem *Item = Fonts.GetHead(); while (Item != NULL) { // Add the font in the list to the combo box AddItem((void *) Item); // Try the next item Item = Fonts.GetNext(Item); } // Re-enable redraw SetListRedraw(TRUE); // We have no concept of a selected font SetSelectedIndex(-1); EndSlowJob(); return(TRUE); }
BOOL OutputPNG::WriteBlock( UINT32 YPos, UINT32 Height, LPBYTE BlockStart, UINT32 InputBPP, INT32 ProgressOffset) { ERROR2IF(DestBitmapInfo == NULL, FALSE,"OutputPNG::WriteBlock destination bitmap info null"); ERROR2IF(DestBitmapBytes == NULL, FALSE,"OutputPNG::WriteBlock destination bitmap bits null"); ERROR2IF(pNextStrip == NULL, FALSE,"OutputPNG::WriteBlock next strip pointer is null"); FNPTR_SCANLINE ConvertFn = NULL; LPBYTE Buffer = NULL; size_t BufSize = 0L; size_t ChunkHeight = 1; DIBConvert *DoConvert = NULL; // Set up the size and other information for the dib block that we require. This is // dependent on the export depth or bpp required. if ( !SetUpBlock( &BufSize, &ChunkHeight, &DoConvert, &ConvertFn ) ) return FALSE; // Error details already set up if (BufSize) { Buffer = (LPBYTE)CCMalloc( BufSize ); if (Buffer==NULL) return FALSE; } if ( DoConvert ) { // use new classes to do it // 8bpp, 4bpp and 1bpp conversion INT32 h = Height; INT32 count = 0; LPBYTE Data = BlockStart; const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP ) * ChunkHeight; const size_t DestWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, BitmapInfo.biBitCount ); while (h) { ENSURE(h >= 0, "bad looping"); const size_t ThisBit = min( h, (INT32)ChunkHeight ); if (!DoConvert->Convert( Data, Buffer, ThisBit, IsFirstStrip )) break; // stop if conversion failed IsFirstStrip = FALSE; // Copy this block to our destination bitmap // pNextStrip should be pointing at the next place to copy the data to memcpy(pNextStrip, Buffer, ThisBit * DestWidth); Data += SourceWidth; h -= ThisBit; pNextStrip += ThisBit * DestWidth; // now update the progress display, started with CurrentExportSize // CurrentExport size is now the point to go from in the export count++; ContinueSlowJob( (INT32)(ProgressOffset + count) ); //ContinueSlowJob( (INT32)(100*count/(Height)) ); } } else if ( ConvertFn && Buffer ) { // Write via conversion function // 24 bpp convert UINT32 h = Height; INT32 count = 0; LPBYTE Data = BlockStart; const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP ); while (h) { ConvertFn( BitmapInfo.biWidth, Data, Buffer ); // Copy this block to our destination bitmap // pNextStrip should be pointing at the next place to copy the data to memcpy(pNextStrip, Buffer, BufSize); Data += SourceWidth; h -= ChunkHeight; pNextStrip += BufSize; // now update the progress display, started with CurrentExportSize // ProgressOffset size is now the point to go from in the export count++; ContinueSlowJob( (INT32)( ProgressOffset + count )); //ContinueSlowJob( (INT32)((CurrentExportSize * count)/Height) ); } } else { // Write the actual bytes out to file. Used to do it in one go but we really // require some progress bar indication so we will do it in chunks. DWORD BitsSize = BitmapInfo.biSizeImage; if (BitsSize > 0) { if (BitsSize < 1024) { // File very small or no progress bar required, so load in one go // Copy this block to our destination bitmap // pNextStrip should be pointing at the next place to copy the data to memcpy(pNextStrip, BlockStart, BitsSize); pNextStrip += BitsSize; } else { // Load in chunks, for present split into 100 chunks DWORD ChunkSize = BitsSize/100; DWORD Position = 0; LPBYTE pBitInfo = BlockStart; while (Position < BitsSize) { if ( (BitsSize - Position) > ChunkSize) { // Copy this block to our destination bitmap // pNextStrip should be pointing at the next place to copy the data to memcpy(pNextStrip, pBitInfo, ChunkSize); } else { ChunkSize = BitsSize - Position; // Copy this block to our destination bitmap // pNextStrip should be pointing at the next place to copy the data to memcpy(pNextStrip, pBitInfo, ChunkSize); } // Increment our counters/pointers Position+=ChunkSize; pBitInfo+=ChunkSize; pNextStrip += ChunkSize; // Progress bar started with height of bitmap ContinueSlowJob( (INT32)(ProgressOffset + (Height * Position)/BitsSize) ); //ContinueSlowJob( (INT32)((CurrentExportSize * Position)/BitsSize) ); } } } } // If present, get rid of our export function if (DoConvert) { delete DoConvert; DoConvert = NULL; } CCFree( Buffer ); HeightWritten += Height; // remember we wrote this lot return TRUE; }
BOOL OutputPNG::OutputPNGBits(CCLexFile *File, LPBYTE pBlockStart, BOOL OneBlock, BaseCamelotFilter *pFilter) { ERROR2IF(File==NULL,FALSE,"OutputPNG::OutputPNGHeader File pointer is null"); ERROR2IF(pBlockStart==NULL,FALSE,"OutputPNG::OutputPNGHeader BitmapInfo pointer is null"); // Check we have the PNG related items claimed (NOTE: p at end means pointer and hence implied *) // This would then imply that OutputPNGHeader has been called ERROR2IF(png_ptr == NULL || info_ptr == NULL,FALSE,"OutputPNG::OutputPNGHeader PNG related items not set up"); // Note file in our class variable as used by all the low level routines OutputFile = File; // Must set the exception throwing flag to True and force reporting of errors to False. // This means that the caller must report an error if the function returns False. // Any calls to CCFile::GotError will now throw a file exception and should fall into // the catch handler at the end of the function. // Replaces the goto's that handled this before. BOOL OldThrowingState = File->SetThrowExceptions( TRUE ); BOOL OldReportingState = File->SetReportErrors( FALSE ); try { // It is now ready to go and put that data onto the disc // so wait for the bitmap data to be prepared // turn on interlace handling if you are not using png_write_image() INT32 number_passes = 1; if (Interlace) number_passes = png_set_interlace_handling(png_ptr); // Work out how often we need to update the progress bar INT32 UpdateEvery = 1; if (pFilter == NULL) { if (number_passes > 1) UpdateEvery = (Height/(100*number_passes) + 1); else UpdateEvery = (Height/100 + 1); } INT32 LastProgressUpdate = 0; // Work out the word/byte rounded line width rather than the pixel width INT32 WidthOfLine = DIBUtil::ScanlineSize( Width, BitsPerPixel ); // The pointer to the actual bitmap data LPBYTE pBitsData = pBlockStart; LPBYTE pData = pBitsData; BOOL JobState = TRUE; // Of course being DIBs we need to write the data out upside down! i.e. bottom to top for (INT32 pass = 0; pass < number_passes; pass++) { pBitsData = pBlockStart; LastProgressUpdate = 0; for (INT32 ypos = 0; ypos < Height; ypos++) { // Read in from bottom upwards pData = pBitsData + ((Height - 1 - ypos) * WidthOfLine); // Write that row out to file png_write_row(png_ptr, pData); // Update the progress count, if required if (ypos > (LastProgressUpdate + UpdateEvery)) { // Note the update point so that we know the next one LastProgressUpdate = ypos; // Now update the progress display, started with 100, but only if pFilter is NULL if (pFilter == NULL) ContinueSlowJob( (INT32)(100 * ypos/Height * (pass + 1)/number_passes) ); else { // Ask the pFilter to update the progress bar for us JobState = TRUE; pFilter->IncProgressBarCount(1); } // If JobState is False then the user has probably pressed escape and we should // immediately stop what we are doing. if (!JobState) { File->GotError(_R(IDW_CANCELEXPORT)); // Expects error set on cancel return FALSE; } } } } // write the rest of the file png_write_end(png_ptr, info_ptr); // Call up function to clean up the png structures CleanUpPngStructures(); // Must set the exception throwing and reporting flags back to their entry states File->SetThrowExceptions( OldThrowingState ); File->SetReportErrors( OldReportingState ); // We have finished so reset the PNG exception handling PNGUtil::SetCCFilePointer(NULL); TRACEUSER( "Jonathan", _T("PNG write: Finished\n")); // er, we seem to have finished OK so say so return TRUE; } // CATCH( CFileException, e) catch (...) { // catch our form of a file exception TRACE( _T("OutputPNG::OutputPNGBits CC catch handler\n")); // Call up function to clean up the png structures CleanUpPngStructures(); // Must set the exception throwing and reporting flags back to their entry states File->SetThrowExceptions( OldThrowingState ); File->SetReportErrors( OldReportingState ); // We have finished so reset the PNG exception handling PNGUtil::SetCCFilePointer(NULL); return FALSE; } ERROR2( FALSE, "Escaped exception clause somehow" ); }
BOOL OrderedList::SortSequence(OrderSequence *TheSeq) { if (TheSeq == NULL || TheSeq->Comparator == NULL) // Error! return(FALSE); if (TheSeq->Cached) // Well, I reckon it's already sorted. Hah return(TRUE); SequenceItem *ItemA; SequenceItem *ItemB; SequenceItem *ItemC; BOOL Sorted; INT32 CompareResult; // Commented out 11/1/95 by Markn because Jason told me to. And it fixes one of my bugs. // Sometimes this gets called when there's already a slow job going (e.g. import with layers with layer gal open). // // BeginSlowJob(-1); // Show hourglass, with delay, no percentage do { Sorted = TRUE; // Assume in sorted order until we have to move an item ItemA = (SequenceItem *) TheSeq->Sequence.GetHead(); while (ItemA != NULL) { ContinueSlowJob(); ItemB = (SequenceItem *) TheSeq->Sequence.GetNext(ItemA); if (ItemB == NULL) // At end of list, so have finished this pass break; if (TheSeq->Reversed) CompareResult = TheSeq->Comparator(this, ItemB->GetItem(), ItemA->GetItem()); else CompareResult = TheSeq->Comparator(this, ItemA->GetItem(), ItemB->GetItem()); if (CompareResult > 0) { Sorted = FALSE; // Have to move an item - can't be in order yet // Delink ItemA from the list - it has to move up TheSeq->Sequence.RemoveItem(ItemA); // Search for proper position for A... ItemC = (SequenceItem *) TheSeq->Sequence.GetNext(ItemB); while (ItemC != NULL) { if (TheSeq->Reversed) CompareResult = TheSeq->Comparator(this, ItemC->GetItem(), ItemA->GetItem()); else CompareResult = TheSeq->Comparator(this, ItemA->GetItem(), ItemC->GetItem()); if (CompareResult <= 0) // Have found place to drop ItemA... break; ItemC = (SequenceItem *) TheSeq->Sequence.GetNext(ItemC); } if (ItemC == NULL) TheSeq->Sequence.AddTail(ItemA); // Belongs at end of list else TheSeq->Sequence.InsertBefore(ItemC, ItemA); // Belongs just before ItemC } ItemA = ItemB; // Loop, from the next unsorted item } } while (!Sorted); // EndSlowJob(); BeginSlowJob() statement see above TheSeq->Cached = TRUE; return(TRUE); }
/******************************************************************************************** > BOOL AIBitmapProcessor::ReadImageData( AI5EPSFilter* const pFilter, const INT32 ImageType, ADDR pData, INT32 nLength ) const Author: Colin_Barfoot (Xara Group Ltd) <*****@*****.**> Created: 23/03/00 Returns: TRUE if the image was read correctly FALSE if the data length differed from the expected given in nLength in,out: pData: A pointer to an allocated block of memory to hold the decoded hexadecimal data. in: nLength: The expected number of bytes decoded from the stream ImageType: The AI ImageType given in the XI definition Purpose: 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. Each line begins %XXXX where XXXX are hex numbers. Assumes that the first % token has not yet been read. ********************************************************************************************/ BOOL AIBitmapProcessor::ReadImageData( AI5EPSFilter& filter, const INT32 ImageType, ADDR pDataStart, INT32 nLength, INT32 nLineLength, INT32 nMaxLineOffset ) { //////////////// // ignore the whitespace (EOL) //////////////// filter.GetEPSFile()->GetToken(); //////////////// // read the first % line //////////////// filter.GetEPSFile()->GetToken(); ///////////////// // We need some running values ///////////////// BYTE ColourVal[4] = {0,0,0,0}; UINT32 nShift = 0; // which colour component is being read //////////////// // start with last line //////////////// ADDR pCurrentLine = pDataStart + nLength - nLineLength; INT32 nLineOffset = 0; while ( pCurrentLine >= pDataStart && !filter.GetEPSFile()->eof() ) { // the data ends with a comment if ( camStrncmp( filter.GetTokenBuf(), _T("%%EndData"), 9 ) == 0 ) break; //////////////// // update progress //////////////// const INT32 nCharsRead = filter.GetEPSFile()->GetCharsRead(); if ( nCharsRead > (filter.GetLastProgressUpdate() + 2048) ) { if ( !ContinueSlowJob( nCharsRead ) ) { // Abort operation - make sure nodes are deleted and not added to the tree. ERROR(_R(IDT_IMPORT_USERABORT), FALSE); } else { filter.GetLastProgressUpdate() = nCharsRead; } } //////////////// // Decode the token into hex data (starting after the %) //////////////// INT32 nBytes = 0; switch ( ImageType ) { case 1: // greyscale nBytes = filter.DecodeHexString( pCurrentLine, nLength, 1 ); break; case 3: // rgb nBytes = DecodeHexStringAsRGB( filter, pCurrentLine, nLineOffset, nLineLength, nMaxLineOffset, 1, ColourVal, nShift ); break; case 4: // CMYK nBytes = DecodeHexStringAsCMYK( filter, pCurrentLine, nLineOffset, nLineLength, nMaxLineOffset, 1, ColourVal, nShift ); break; } if ( nBytes == -1 ) { // Error TRACE( _T("Error in AI5 image data\n") ); break; } /////////////// // get the next token /////////////// filter.GetEPSFile()->GetToken(); } return ( pDataStart - pCurrentLine == nLineLength ) ? TRUE : FALSE; }