#include <outptpng.h>
Inheritance diagram for OutputPNG:
Public Member Functions | |
OutputPNG () | |
Default constructor for the class. Just sets up the pointers to our buffers that may be used to be null so that the TidyUp function can do its job. | |
virtual BOOL | StartFile (LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette, UINT32 OutputDepth, DWORD CompressionType, UINT32 FinalHeight, INT32 ExportSize, UINT32 DitherType) |
Get ready to write a PNG to disk, maybe in chunks. In the DIB case we go out to disk, in this case we store the bitmap for possible later use in applying a transparency mask to it. | |
virtual BOOL | ReStartFile (LOGPALETTE *pNewPal) |
Called to reset output before outputing another in a run of multiple images. | |
virtual BOOL | WriteBlock (UINT32 YPos, UINT32 Height, LPBYTE BlockStart, UINT32 InputBPP=32, INT32 ProgressOffset=0) |
Writes a chunk of bitmap data to the device. Assumes a progress hourglass is required and the caller has started an hourglass with a size of 100 and will end it. Notes: Originally this routine assumed that it was being given a 32bpp bmp, but using the InputBPP param it will now handle 8bpp bmps as well... | |
virtual BOOL | SetUpInfoHeader (const LPBITMAPINFOHEADER lpHeader, const UINT32 OutputDepth, const DWORD CompressionType, const UINT32 LIneWidth, const UINT32 FinalHeight, INT32 *PalSize) |
Set up the information header for the DIB. | |
virtual BOOL | TidyUp () |
When everything has been done via WriteBlock, call this to update the header etc. The caller is responsible for closing the file. The class CANNOT be used for further output until StartFile is called again. | |
BOOL | OutputPNGHeader (CCLexFile *File, INT32 TransColour, BOOL InterlaceState=0) |
Writes out the file header for the cached bitmap within this class. | |
BOOL | OutputPNGHeader (CCLexFile *File, LPBITMAPINFOHEADER pInfo, BOOL InterlaceState, INT32 TransparentColour, LPLOGPALETTE pPalette=NULL, LPRGBQUAD pQuadPalette=NULL) |
Output a PNG header for the specified bitmap to the file. If neither palette is specifed then none will be output. | |
BOOL | OutputPNGBits (CCLexFile *File, LPBYTE pBlockStart, BOOL OneBlock=TRUE, BaseCamelotFilter *pFilter=NULL) |
Output the actual bits of a bitmap as compressed PNG data. Assumes that a header has already been output, possibly using OutputPNGHeader. Assumes that all the data is present. | |
virtual LPBITMAPINFO | GetDestBitmapInfo (void) |
Access function to DestBitmapInfo. | |
virtual LPBYTE | GetDestBitmapBits (void) |
Access function to DestBitmapBytes. | |
Private Member Functions | |
BOOL | CleanUpPngStructures () |
Clean up those bits that may have been claimed by the PNG bits. | |
Private Attributes | |
LPBITMAPINFO | DestBitmapInfo |
LPBYTE | DestBitmapBytes |
LPBYTE | pNextStrip |
png_structp | png_ptr |
png_infop | info_ptr |
INT32 | Width |
INT32 | Height |
BOOL | Interlace |
BOOL | Transparent |
INT32 | BitsPerPixel |
INT32 | InitCodeSize |
LPBYTE | DataBuffer |
UINT32 | WidthOfLine |
Definition at line 131 of file outptpng.h.
|
Default constructor for the class. Just sets up the pointers to our buffers that may be used to be null so that the TidyUp function can do its job.
Definition at line 136 of file outptpng.cpp. 00137 { 00138 OutputFile = NULL; 00139 lpBitmap = NULL; 00140 ExportBuffer = NULL; 00141 DoExportConvert = NULL; 00142 OutputForward = FALSE; 00143 00144 DestBitmapInfo = NULL; 00145 DestBitmapBytes = NULL; 00146 }
|
|
Clean up those bits that may have been claimed by the PNG bits.
Definition at line 773 of file outptpng.cpp. 00774 { 00775 // If our structures are present then clean them out 00776 if (png_ptr) 00777 { 00778 if (info_ptr) 00779 { 00780 // They do not seem to have catered for the palette and transparency structures 00781 if (info_ptr->palette) 00782 { 00783 CCFree(info_ptr->palette); 00784 info_ptr->palette = NULL; 00785 } 00786 if (info_ptr->trans) 00787 { 00788 CCFree(info_ptr->trans); 00789 info_ptr->trans = NULL; 00790 } 00791 } 00792 00793 // clean up after the write, and free any memory allocated 00794 png_destroy_write_struct(&png_ptr, &info_ptr); 00795 png_ptr = NULL; 00796 } 00797 00798 return TRUE; 00799 }
|
|
Access function to DestBitmapBytes.
Reimplemented from OutputDIB. Definition at line 984 of file outptpng.cpp. 00985 { 00986 return DestBitmapBytes; 00987 }
|
|
Access function to DestBitmapInfo.
Reimplemented from OutputDIB. Definition at line 967 of file outptpng.cpp. 00968 { 00969 return DestBitmapInfo; 00970 }
|
|
Output the actual bits of a bitmap as compressed PNG data. Assumes that a header has already been output, possibly using OutputPNGHeader. Assumes that all the data is present.
Definition at line 827 of file outptpng.cpp. 00829 { 00830 ERROR2IF(File==NULL,FALSE,"OutputPNG::OutputPNGHeader File pointer is null"); 00831 ERROR2IF(pBlockStart==NULL,FALSE,"OutputPNG::OutputPNGHeader BitmapInfo pointer is null"); 00832 // Check we have the PNG related items claimed (NOTE: p at end means pointer and hence implied *) 00833 // This would then imply that OutputPNGHeader has been called 00834 ERROR2IF(png_ptr == NULL || info_ptr == NULL,FALSE,"OutputPNG::OutputPNGHeader PNG related items not set up"); 00835 00836 // Note file in our class variable as used by all the low level routines 00837 OutputFile = File; 00838 00839 // Must set the exception throwing flag to True and force reporting of errors to False. 00840 // This means that the caller must report an error if the function returns False. 00841 // Any calls to CCFile::GotError will now throw a file exception and should fall into 00842 // the catch handler at the end of the function. 00843 // Replaces the goto's that handled this before. 00844 BOOL OldThrowingState = File->SetThrowExceptions( TRUE ); 00845 BOOL OldReportingState = File->SetReportErrors( FALSE ); 00846 00847 try 00848 { 00849 // It is now ready to go and put that data onto the disc 00850 // so wait for the bitmap data to be prepared 00851 00852 // turn on interlace handling if you are not using png_write_image() 00853 INT32 number_passes = 1; 00854 if (Interlace) 00855 number_passes = png_set_interlace_handling(png_ptr); 00856 00857 // Work out how often we need to update the progress bar 00858 INT32 UpdateEvery = 1; 00859 if (pFilter == NULL) 00860 { 00861 if (number_passes > 1) 00862 UpdateEvery = (Height/(100*number_passes) + 1); 00863 else 00864 UpdateEvery = (Height/100 + 1); 00865 } 00866 INT32 LastProgressUpdate = 0; 00867 // Work out the word/byte rounded line width rather than the pixel width 00868 INT32 WidthOfLine = DIBUtil::ScanlineSize( Width, BitsPerPixel ); 00869 // The pointer to the actual bitmap data 00870 LPBYTE pBitsData = pBlockStart; 00871 LPBYTE pData = pBitsData; 00872 BOOL JobState = TRUE; 00873 00874 // Of course being DIBs we need to write the data out upside down! i.e. bottom to top 00875 for (INT32 pass = 0; pass < number_passes; pass++) 00876 { 00877 pBitsData = pBlockStart; 00878 LastProgressUpdate = 0; 00879 for (INT32 ypos = 0; ypos < Height; ypos++) 00880 { 00881 // Read in from bottom upwards 00882 pData = pBitsData + ((Height - 1 - ypos) * WidthOfLine); 00883 00884 // Write that row out to file 00885 png_write_row(png_ptr, pData); 00886 00887 // Update the progress count, if required 00888 if (ypos > (LastProgressUpdate + UpdateEvery)) 00889 { 00890 // Note the update point so that we know the next one 00891 LastProgressUpdate = ypos; 00892 00893 // Now update the progress display, started with 100, but only if pFilter is NULL 00894 if (pFilter == NULL) 00895 ContinueSlowJob( (INT32)(100 * ypos/Height * (pass + 1)/number_passes) ); 00896 else 00897 { 00898 // Ask the pFilter to update the progress bar for us 00899 JobState = TRUE; 00900 pFilter->IncProgressBarCount(1); 00901 } 00902 00903 // If JobState is False then the user has probably pressed escape and we should 00904 // immediately stop what we are doing. 00905 if (!JobState) 00906 { 00907 File->GotError(_R(IDW_CANCELEXPORT)); // Expects error set on cancel 00908 return FALSE; 00909 } 00910 } 00911 } 00912 } 00913 00914 // write the rest of the file 00915 png_write_end(png_ptr, info_ptr); 00916 00917 // Call up function to clean up the png structures 00918 CleanUpPngStructures(); 00919 00920 // Must set the exception throwing and reporting flags back to their entry states 00921 File->SetThrowExceptions( OldThrowingState ); 00922 File->SetReportErrors( OldReportingState ); 00923 00924 // We have finished so reset the PNG exception handling 00925 PNGUtil::SetCCFilePointer(NULL); 00926 00927 TRACEUSER( "Jonathan", _T("PNG write: Finished\n")); 00928 00929 // er, we seem to have finished OK so say so 00930 return TRUE; 00931 } 00932 00933 // CATCH( CFileException, e) 00934 catch (...) 00935 { 00936 // catch our form of a file exception 00937 TRACE( _T("OutputPNG::OutputPNGBits CC catch handler\n")); 00938 00939 // Call up function to clean up the png structures 00940 CleanUpPngStructures(); 00941 00942 // Must set the exception throwing and reporting flags back to their entry states 00943 File->SetThrowExceptions( OldThrowingState ); 00944 File->SetReportErrors( OldReportingState ); 00945 00946 // We have finished so reset the PNG exception handling 00947 PNGUtil::SetCCFilePointer(NULL); 00948 00949 return FALSE; 00950 } 00951 00952 ERROR2( FALSE, "Escaped exception clause somehow" ); 00953 }
|
|
Output a PNG header for the specified bitmap to the file. If neither palette is specifed then none will be output.
Definition at line 448 of file outptpng.cpp. 00451 { 00452 ERROR2IF(File==NULL,FALSE,"OutputPNG::OutputPNGHeader File pointer is null"); 00453 if (pInfo == NULL) 00454 pInfo = &(DestBitmapInfo->bmiHeader); 00455 ERROR2IF(pInfo==NULL,FALSE,"OutputPNG::OutputPNGHeader BitmapInfo pointer is null"); 00456 //ERROR2IF(pPalette==NULL && pQuadPalette==NULL,FALSE,"OutputPNG::OutputPNGHeader Bitmap palette pointer is null"); 00457 00458 TRACEUSER( "Jonathan", _T("PNG write: Interlace: %s\n"), InterlaceState ? _T("Yes") : _T("No")); 00459 00460 // Note file in our class variable as used by all the low level routines 00461 OutputFile = File; 00462 00463 // Note the specified transparency and interlace states in our class variables 00464 Interlace = InterlaceState; 00465 if (TransparentColour != -1) 00466 Transparent = TRUE; 00467 else 00468 Transparent = FALSE; 00469 00470 // We are just about to start so set the PNG exception handling up with our CCFile pointer 00471 PNGUtil::SetCCFilePointer(File); 00472 00473 // Must set the exception throwing flag to True and force reporting of errors to False. 00474 // This means that the caller must report an error if the function returns False. 00475 // Any calls to CCFile::GotError will now throw a file exception and should fall into 00476 // the catch handler at the end of the function. 00477 // Replaces the goto's that handled this before. 00478 BOOL OldThrowingState = File->SetThrowExceptions( TRUE ); 00479 BOOL OldReportingState = File->SetReportErrors( FALSE ); 00480 00481 // PNG related items (NOTE: p at end means pointer and hence implied *) 00482 png_ptr = NULL; 00483 info_ptr = NULL; 00484 00485 try 00486 { 00487 // Work out the palette size 00488 INT32 PalSize = pInfo->biClrUsed; // How many entries in palette 00489 TRACEUSER( "Jonathan", _T("PNG write: PalSize = %d\n"),PalSize); 00490 00491 // Set up the class variables 00492 // First the width/height of the bitmap 00493 Width = pInfo->biWidth; 00494 Height = pInfo->biHeight; 00495 TRACEUSER( "Jonathan", _T("PNG write: Width = %d Height = %d\n"),Width,Height); 00496 00497 BitsPerPixel = pInfo->biBitCount; 00498 00499 // Start up the PNG writing code 00500 00501 // allocate the necessary structures 00502 // Use the default handlers 00503 png_ptr = png_create_write_struct_2( 00504 PNG_LIBPNG_VER_STRING, // libpng version 00505 0, // Optional pointer to be sent with errors 00506 camelot_png_error, // Function called in case of error 00507 camelot_png_warning, // Function called for warnings 00508 0, // Optional pointer to be sent with mem ops 00509 camelot_png_malloc, // Function called to alloc memory 00510 camelot_png_free // Function called to free memory 00511 ); 00512 00513 if (!png_ptr) 00514 File->GotError( _R(IDS_OUT_OF_MEMORY) ); 00515 00516 info_ptr = png_create_info_struct(png_ptr); 00517 if (!info_ptr) 00518 { 00519 png_destroy_write_struct(&png_ptr, (png_infopp)NULL); 00520 File->GotError( _R(IDS_OUT_OF_MEMORY) ); 00521 } 00522 00523 // set up the input control to the fstream class 00524 // If not a disk file then panic for the present moment 00525 // Could use the memfile functions for reading and writing as they give us what 00526 // we want. Use the io_ptr and 00527 iostream* pFStream = File->GetIOFile(); 00528 if (pFStream == NULL) 00529 { 00530 TRACEUSER( "Jonathan", _T("PNG write: OutputPNG::OutputPNGHeader No access to IOStream!")); 00531 File->GotError( _R(IDS_UNKNOWN_PNG_ERROR) ); 00532 } 00533 00534 // Should use our own function 00535 png_set_write_fn(png_ptr, pFStream, camelot_png_write_data, camelot_png_flush_data); 00536 // png_init_io(png_ptr, pFStream); 00537 00538 // You now have the option of modifying how the compression library 00539 // will run. The following functions are mainly for testing, but 00540 // may be useful in certain special cases, like if you need to 00541 // write png files extremely fast and are willing to give up some 00542 // compression, or if you want to get the maximum possible compression 00543 // at the expense of slower writing. If you have no special needs 00544 // in this area, let the library do what it wants, as it has been 00545 // carefully tuned to deliver the best speed/compression ratio. 00546 // See the compression library for more details. 00547 00548 // turn on or off filtering (1 or 0) 00549 //png_set_filtering(png_ptr, 1); 00550 00551 // compression level (0 - none, 6 - default, 9 - maximum) 00552 //png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); 00553 //png_set_compression_mem_level(png_ptr, 8); 00554 //png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); 00555 //png_set_compression_window_bits(png_ptr, 15); 00556 //png_set_compression_method(png_ptr, 8); 00557 00558 info_ptr->valid = 0; // - this describes which optional chunks to write to the 00559 // file. Note that if you are writing a 00560 // PNG_COLOR_TYPE_PALETTE file, the PLTE chunk is not 00561 // optional, but must still be marked for writing. To 00562 // mark chunks for writing, OR valid with the 00563 // appropriate PNG_INFO_<chunk name> define. 00564 // Set the file information here 00565 info_ptr->width = Width; // - holds the width of the file 00566 info_ptr->height = Height; // - holds the height of the file 00567 00568 // resolution of image 00569 info_ptr->valid |= PNG_INFO_pHYs; 00570 info_ptr->x_pixels_per_unit = pInfo->biXPelsPerMeter; 00571 info_ptr->y_pixels_per_unit = pInfo->biYPelsPerMeter; 00572 info_ptr->phys_unit_type = 1; // meter 00573 TRACEUSER( "Jonathan", _T("PNG write: X,y dpi = %d %d\n"),info_ptr->x_pixels_per_unit, info_ptr->y_pixels_per_unit); 00574 if (InterlaceState) 00575 info_ptr->interlace_type = 1; // - currently 0 for none, 1 for interlaced 00576 else 00577 info_ptr->interlace_type = 0; // - currently 0 for none, 1 for interlaced 00578 00579 BitsPerPixel = pInfo->biBitCount; 00580 TRACEUSER( "Jonathan", _T("PNG write: Bitdepth = %d\n"),BitsPerPixel); 00581 info_ptr->palette = NULL; 00582 info_ptr->num_palette = 0; 00583 //info_ptr->trans_values = 0; // - transparent pixel for non-paletted images 00584 info_ptr->trans = NULL; // - array of transparent entries for paletted images 00585 info_ptr->num_trans = 0; // - number of transparent entries 00586 TRACEUSER( "Jonathan", _T("PNG write: TransColour = %d\n"),TransparentColour); 00587 if ( BitsPerPixel <= 8 ) 00588 { 00589 info_ptr->bit_depth = BitsPerPixel; // - holds the bit depth of one of the image channels 00590 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; // - describes the channels and what they mean 00591 // see the PNG_COLOR_TYPE_ defines for more information 00592 // set the palette if there is one 00593 info_ptr->valid |= PNG_INFO_PLTE; 00594 INT32 PaletteEntries = pInfo->biClrUsed; 00595 info_ptr->palette = (png_color_struct *)CCMalloc(PaletteEntries * sizeof (png_color)); 00596 if (info_ptr->palette == NULL) 00597 File->GotError( _R(IDS_OUT_OF_MEMORY) ); 00598 00599 info_ptr->num_palette = PaletteEntries; 00600 png_color_struct * pPNGPalette = info_ptr->palette; 00601 // ... set palette colors ... 00602 if (pQuadPalette && PaletteEntries > 0) 00603 { 00604 // Palette supplied in RGBQUAD form 00605 for (INT32 i = 0; i < PaletteEntries; i++) 00606 { 00607 pPNGPalette->red = pQuadPalette->rgbRed; 00608 pPNGPalette->green = pQuadPalette->rgbGreen; 00609 pPNGPalette->blue = pQuadPalette->rgbBlue; 00610 // skip to the next palette entry 00611 pQuadPalette++; 00612 pPNGPalette++; 00613 } 00614 } 00615 else if (pPalette && PaletteEntries > 0) 00616 { 00617 // Palette supplied in LOGPALETTE form 00618 for (INT32 i = 0; i < PaletteEntries; i++) 00619 { 00620 pPNGPalette->red = pPalette->palPalEntry[i].peRed; 00621 pPNGPalette->green = pPalette->palPalEntry[i].peGreen; 00622 pPNGPalette->blue = pPalette->palPalEntry[i].peBlue; 00623 pPNGPalette++; 00624 } 00625 } 00626 else 00627 File->GotError(_R(IDS_PNG_ERR_WRITE_PALETTE)); 00628 00629 // Now check to see if transparency is present or not 00630 if (TransparentColour >= 0 && TransparentColour <= PaletteEntries ) 00631 { 00632 // Create the array of transparent entries for this palette 00633 // 0 is fully transparent, 255 is fully opaque, regardless of image bit depth 00634 // We will only create as many as we require, i.e. up to the transparent colour entry 00635 // rather a full palettes worth 00636 INT32 NumEntries = TransparentColour + 1; 00637 info_ptr->trans = (png_byte *)CCMalloc(NumEntries * sizeof (png_byte)); 00638 if (info_ptr->trans) 00639 { 00640 // Set the number of transparent entries 00641 info_ptr->num_trans = NumEntries; 00642 png_byte * pTransEntry = info_ptr->trans; 00643 info_ptr->valid |= PNG_INFO_tRNS; 00644 for (INT32 i = 0; i < TransparentColour; i++) 00645 { 00646 *pTransEntry = 255; // set it fully opaque 00647 pTransEntry++; 00648 } 00649 // We should now be at the transparent entry so set it fully transparent 00650 *pTransEntry = 0; 00651 } 00652 } 00653 } 00654 else if (BitsPerPixel == 24) 00655 { 00656 // We must be 24 bpp 00657 info_ptr->bit_depth = BitsPerPixel/3; // - holds the bit depth of one of the image channels 00658 info_ptr->color_type = PNG_COLOR_TYPE_RGB; // - describes the channels and what they mean 00659 // optional significant bit chunk 00660 //info_ptr->valid |= PNG_INFO_sBIT; 00661 // otherwise, if we are dealing with a color image then 00662 //info_ptr->sig_bit.red = BitsPerPixel/3; 00663 //info_ptr->sig_bit.green = BitsPerPixel/3; 00664 //info_ptr->sig_bit.blue = BitsPerPixel/3; 00665 //info_ptr->sig_bit.gray = 0; 00666 //info_ptr->sig_bit.alpha = 0; 00667 } 00668 else if (BitsPerPixel == 32) 00669 { 00670 // We must be a 32 bpp 00671 info_ptr->bit_depth = BitsPerPixel/4; // - holds the bit depth of one of the image channels 00672 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; // - describes the channels and what they mean 00673 // optional significant bit chunk 00674 //info_ptr->valid |= PNG_INFO_sBIT; 00675 // otherwise, if we are dealing with a color image then 00676 //info_ptr->sig_bit.red = BitsPerPixel/4; 00677 //info_ptr->sig_bit.green = BitsPerPixel/4; 00678 //info_ptr->sig_bit.blue = BitsPerPixel/4; 00679 // if the image has an alpha channel then 00680 //info_ptr->sig_bit.alpha = BitsPerPixel/4; 00681 //info_ptr->sig_bit.gray = 0; 00682 00683 // get rid of filler bytes, pack rgb into 3 bytes. The filler number is not used. 00684 // Only required if stripping 32bpp down to 24bpp 00685 //png_set_filler(png_ptr, 0xFF, PNG_FILLER_BEFORE); 00686 } 00687 else 00688 ERROR2(FALSE,"OutputPNG::OutputPNGHeader Unknown bit depth"); 00689 00690 TRACEUSER( "Jonathan", _T("PNG write: bit_depth = %d color_type = %d\n"),info_ptr->bit_depth,info_ptr->color_type); 00691 00692 // Could use:- 00693 // if we are dealing with a grayscale image then 00694 //info_ptr->sig_bit.gray = true_bit_depth; 00695 00696 // gamma - the gamma the file is written at 00697 info_ptr->hist = NULL; // - histogram of palette 00698 info_ptr->text = NULL; // - text comments in the file. 00699 info_ptr->num_text = 0; // - number of comments 00700 00701 // optional gamma chunk is strongly suggested if you have any guess 00702 // as to the correct gamma of the image 00703 //info_ptr->valid |= PNG_INFO_gAMA; 00704 //info_ptr->gamma = gamma; 00705 00706 // other optional chunks 00707 00708 // write the file information 00709 png_write_info(png_ptr, info_ptr); 00710 00711 TRACEUSER( "Jonathan", _T("PNG write: pixel_depth %d channels %d\n"),png_ptr->pixel_depth, png_ptr->channels); 00712 TRACEUSER( "Jonathan", _T("PNG write: rowbytes %d color_type %d\n"),png_ptr->rowbytes, png_ptr->color_type); 00713 // Set up the transformations you want. 00714 // Note: that these are all optional. Only call them if you want them 00715 00716 // invert monocrome pixels 00717 //png_set_invert(png_ptr); 00718 00719 // shift the pixels up to a legal bit depth and fill in as appropriate 00720 // to correctly scale the image 00721 //png_set_shift(png_ptr, &(info_ptr->sig_bit)); 00722 00723 // pack pixels into bytes 00724 //png_set_packing(png_ptr); 00725 00726 png_set_bgr(png_ptr); 00727 00728 // swap bytes of 16 bit files to most significant bit first 00729 png_set_swap(png_ptr); 00730 00731 // Must set the exception throwing and reporting flags back to their entry states 00732 File->SetThrowExceptions( OldThrowingState ); 00733 File->SetReportErrors( OldReportingState ); 00734 00735 // er, we seem to have finished OK so say so 00736 return TRUE; 00737 } 00738 00739 catch (...) 00740 { 00741 // catch our form of a file exception 00742 TRACE( _T("OutputPNG::OutputPNGHeader CC catch handler\n")); 00743 00744 // Call up function to clean up the png structures 00745 CleanUpPngStructures(); 00746 00747 // Must set the exception throwing and reporting flags back to their entry states 00748 File->SetThrowExceptions( OldThrowingState ); 00749 File->SetReportErrors( OldReportingState ); 00750 00751 // We have finished so reset the PNG exception handling 00752 PNGUtil::SetCCFilePointer(NULL); 00753 00754 return FALSE; 00755 } 00756 00757 ERROR2( FALSE, "Escaped exception clause somehow" ); 00758 }
|
|
Writes out the file header for the cached bitmap within this class.
Definition at line 418 of file outptpng.cpp. 00419 { 00420 return OutputPNGHeader(File, &(DestBitmapInfo->bmiHeader), InterlaceState, TransColour, OutputPalette); 00421 }
|
|
Called to reset output before outputing another in a run of multiple images.
Definition at line 273 of file outptpng.cpp. 00274 { 00275 // Reset member variables 00276 IsFirstStrip = TRUE; 00277 HeightWritten = 0; 00278 pNextStrip = DestBitmapBytes; 00279 00280 if (pNewPal!=NULL) 00281 { 00282 ERROR2IF(OutputPalette==NULL, FALSE, "No output palette"); 00283 ERROR3IF(pNewPal->palNumEntries != OutputPalette->palNumEntries, "Different sized palettes"); 00284 00285 const size_t PalSize = sizeof(PALETTEENTRY) * pNewPal->palNumEntries-1; 00286 memcpy( OutputPalette->palPalEntry, pNewPal->palPalEntry, PalSize ); 00287 } 00288 00289 return TRUE; 00290 }
|
|
Set up the information header for the DIB.
Definition at line 316 of file outptpng.cpp. 00320 { 00321 ERROR2IF(pPalSize == NULL,FALSE,"OutputPNG::SetUpInfoHeader Null pPalSize"); 00322 00323 SourceBitmapDepth = lpHeader->biBitCount; 00324 BitmapInfo.biBitCount = OutputDepth; 00325 00326 const WORD DestDepth = BitmapInfo.biBitCount; 00327 00328 // source bitmap not necessarily same as required file depth 00329 // make sure we can handle conversion 00330 BOOL FormatOK = FALSE; 00331 *pPalSize = 0; 00332 00333 switch (SourceBitmapDepth) 00334 { 00335 case 32: 00336 { 00337 switch (DestDepth) 00338 { 00339 case 32: 00340 { 00341 // 32->32 might use our special type CC_BMPTYPE 00342 FormatOK = TRUE; 00343 } 00344 break; 00345 case 24: 00346 { 00347 // 32->24 bit is fine 00348 FormatOK = TRUE; 00349 } 00350 break; 00351 case 8: 00352 { 00353 // 32->8 is OK 00354 FormatOK = TRUE; 00355 *pPalSize = 256; 00356 } 00357 break; 00358 case 4: 00359 { 00360 // 32->4 is OK 00361 FormatOK = TRUE; 00362 *pPalSize = 16; 00363 } 00364 break; 00365 case 1: 00366 { 00367 // 32->1 is OK 00368 FormatOK = TRUE; 00369 *pPalSize = 2; 00370 } 00371 break; 00372 default: 00373 // other source formats here 00374 break; 00375 } 00376 00377 } 00378 break; 00379 case 8: 00380 if (DestDepth==8) 00381 { 00382 // 8->8 is OK 00383 FormatOK = TRUE; 00384 *pPalSize = 256; 00385 } 00386 break; 00387 default: 00388 // other source formats here 00389 break; 00390 } 00391 00392 if (!FormatOK) 00393 { 00394 Error::SetError( _R(IDE_FORMATNOTSUPPORTED) ); 00395 return FALSE; 00396 } 00397 00398 BitmapInfo.biSizeImage = LineWidth * FinalHeight; 00399 00400 return TRUE; 00401 }
|
|
Get ready to write a PNG to disk, maybe in chunks. In the DIB case we go out to disk, in this case we store the bitmap for possible later use in applying a transparency mask to it.
Reimplemented from OutputDIB. Definition at line 176 of file outptpng.cpp. 00179 { 00180 TRACEUSER( "Jonathan", _T("PNG write: Start\n")); 00181 ERROR2IF( lpHeader==NULL , FALSE, "OutputPNG::StartFile NULL lpHeader"); 00182 00183 // Set up memory pointers to NULL 00184 if (DestBitmapInfo && DestBitmapBytes) 00185 { 00186 FreeDIB( DestBitmapInfo, DestBitmapBytes ); 00187 DestBitmapInfo = NULL; 00188 DestBitmapBytes = NULL; 00189 } 00190 // DestBitmapInfo = NULL; 00191 // DestBitmapBytes = NULL; 00192 if (OutputPalette) 00193 { 00194 CCFree(OutputPalette); 00195 OutputPalette = NULL; 00196 } 00197 // OutputPalette = NULL; 00198 IsFirstStrip = TRUE; 00199 HeightWritten = 0; 00200 00201 // remember input args 00202 BitmapInfo = *lpHeader; // take a copy of user's header 00203 CurrentExportSize = ExportSize; // size set up for the progress bar 00204 HeightWanted = FinalHeight; // the actual height of the export required 00205 Dither = DitherType; 00206 00207 // We will need to have the entire image present before writing out so that we can 00208 // cope with interlacing and transparency, so create that DIB 00209 // Set up the information header for the dib which we hold during export 00210 UINT32 LineWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, OutputDepth ); 00211 INT32 PalSize = 0; 00212 BOOL ok = SetUpInfoHeader(lpHeader, OutputDepth, CompressionType, LineWidth, FinalHeight, &PalSize); 00213 00214 // Claim memory for the bitmap 00215 if (ok) 00216 { 00217 DestBitmapInfo = AllocDIB( BitmapInfo.biWidth, FinalHeight, OutputDepth, &DestBitmapBytes ); 00218 ok = (DestBitmapInfo != NULL) && (DestBitmapBytes != NULL); 00219 } 00220 00221 // Transfer across the required other bits of info 00222 if (ok) 00223 { 00224 DestBitmapInfo->bmiHeader.biXPelsPerMeter = BitmapInfo.biXPelsPerMeter; 00225 DestBitmapInfo->bmiHeader.biYPelsPerMeter = BitmapInfo.biYPelsPerMeter; 00226 DestBitmapInfo->bmiHeader.biClrUsed = PalSize; 00227 } 00228 00229 // Point the place to put the next strip of data at the start ready for the first strip 00230 pNextStrip = DestBitmapBytes; 00231 00232 // Take a copy of the palette 00233 if (ok && PalSize && Palette) 00234 { 00235 const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PalSize ); 00236 OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal ); 00237 if (OutputPalette != NULL) 00238 memcpy( OutputPalette, Palette, TotalPal ); 00239 else 00240 ok = FALSE; 00241 } 00242 00243 // Clean up if an error happened 00244 if (!ok) 00245 { 00246 // Free up the DIB that we have just created 00247 FreeDIB( DestBitmapInfo, DestBitmapBytes ); 00248 DestBitmapInfo = NULL; 00249 DestBitmapBytes = NULL; 00250 if (OutputPalette != NULL) 00251 { 00252 CCFree(OutputPalette); 00253 OutputPalette = NULL; 00254 } 00255 } 00256 00257 return ok; 00258 }
|
|
When everything has been done via WriteBlock, call this to update the header etc. The caller is responsible for closing the file. The class CANNOT be used for further output until StartFile is called again.
Reimplemented from OutputDIB. Definition at line 1180 of file outptpng.cpp. 01181 { 01182 // Just in case we have any png related bits left around 01183 // Call up function to clean up the png structures 01184 CleanUpPngStructures(); 01185 01186 // Free up the DIB that we have just created 01187 if (DestBitmapInfo && DestBitmapBytes) 01188 { 01189 FreeDIB( DestBitmapInfo, DestBitmapBytes ); 01190 DestBitmapInfo = NULL; 01191 DestBitmapBytes = NULL; 01192 } 01193 01194 // Call the baseclass version to do its stuff 01195 const BOOL ok = OutputDIB::TidyUp(); 01196 01197 return ok; 01198 }
|
|
Writes a chunk of bitmap data to the device. Assumes a progress hourglass is required and the caller has started an hourglass with a size of 100 and will end it. Notes: Originally this routine assumed that it was being given a 32bpp bmp, but using the InputBPP param it will now handle 8bpp bmps as well...
Reimplemented from OutputDIB. Definition at line 1013 of file outptpng.cpp. 01015 { 01016 ERROR2IF(DestBitmapInfo == NULL, FALSE,"OutputPNG::WriteBlock destination bitmap info null"); 01017 ERROR2IF(DestBitmapBytes == NULL, FALSE,"OutputPNG::WriteBlock destination bitmap bits null"); 01018 ERROR2IF(pNextStrip == NULL, FALSE,"OutputPNG::WriteBlock next strip pointer is null"); 01019 01020 FNPTR_SCANLINE ConvertFn = NULL; 01021 LPBYTE Buffer = NULL; 01022 size_t BufSize = 0L; 01023 size_t ChunkHeight = 1; 01024 DIBConvert *DoConvert = NULL; 01025 01026 // Set up the size and other information for the dib block that we require. This is 01027 // dependent on the export depth or bpp required. 01028 if ( !SetUpBlock( &BufSize, &ChunkHeight, &DoConvert, &ConvertFn ) ) 01029 return FALSE; // Error details already set up 01030 01031 if (BufSize) 01032 { 01033 Buffer = (LPBYTE)CCMalloc( BufSize ); 01034 if (Buffer==NULL) 01035 return FALSE; 01036 } 01037 01038 if ( DoConvert ) 01039 { 01040 // use new classes to do it 01041 // 8bpp, 4bpp and 1bpp conversion 01042 INT32 h = Height; 01043 INT32 count = 0; 01044 LPBYTE Data = BlockStart; 01045 const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP ) * ChunkHeight; 01046 const size_t DestWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, BitmapInfo.biBitCount ); 01047 01048 while (h) 01049 { 01050 ENSURE(h >= 0, "bad looping"); 01051 01052 const size_t ThisBit = min( h, (INT32)ChunkHeight ); 01053 if (!DoConvert->Convert( Data, Buffer, ThisBit, IsFirstStrip )) 01054 break; // stop if conversion failed 01055 01056 IsFirstStrip = FALSE; 01057 01058 // Copy this block to our destination bitmap 01059 // pNextStrip should be pointing at the next place to copy the data to 01060 memcpy(pNextStrip, Buffer, ThisBit * DestWidth); 01061 01062 Data += SourceWidth; 01063 h -= ThisBit; 01064 pNextStrip += ThisBit * DestWidth; 01065 01066 // now update the progress display, started with CurrentExportSize 01067 // CurrentExport size is now the point to go from in the export 01068 count++; 01069 ContinueSlowJob( (INT32)(ProgressOffset + count) ); 01070 //ContinueSlowJob( (INT32)(100*count/(Height)) ); 01071 } 01072 } 01073 else if ( ConvertFn && Buffer ) 01074 { 01075 // Write via conversion function 01076 // 24 bpp convert 01077 UINT32 h = Height; 01078 INT32 count = 0; 01079 LPBYTE Data = BlockStart; 01080 const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP ); 01081 01082 while (h) 01083 { 01084 ConvertFn( BitmapInfo.biWidth, Data, Buffer ); 01085 01086 // Copy this block to our destination bitmap 01087 // pNextStrip should be pointing at the next place to copy the data to 01088 memcpy(pNextStrip, Buffer, BufSize); 01089 01090 Data += SourceWidth; 01091 h -= ChunkHeight; 01092 pNextStrip += BufSize; 01093 01094 // now update the progress display, started with CurrentExportSize 01095 // ProgressOffset size is now the point to go from in the export 01096 count++; 01097 ContinueSlowJob( (INT32)( ProgressOffset + count )); 01098 //ContinueSlowJob( (INT32)((CurrentExportSize * count)/Height) ); 01099 } 01100 } 01101 else 01102 { 01103 // Write the actual bytes out to file. Used to do it in one go but we really 01104 // require some progress bar indication so we will do it in chunks. 01105 DWORD BitsSize = BitmapInfo.biSizeImage; 01106 if (BitsSize > 0) 01107 { 01108 if (BitsSize < 1024) 01109 { 01110 // File very small or no progress bar required, so load in one go 01111 // Copy this block to our destination bitmap 01112 // pNextStrip should be pointing at the next place to copy the data to 01113 memcpy(pNextStrip, BlockStart, BitsSize); 01114 pNextStrip += BitsSize; 01115 } 01116 else 01117 { 01118 // Load in chunks, for present split into 100 chunks 01119 DWORD ChunkSize = BitsSize/100; 01120 DWORD Position = 0; 01121 LPBYTE pBitInfo = BlockStart; 01122 01123 while (Position < BitsSize) 01124 { 01125 if ( (BitsSize - Position) > ChunkSize) 01126 { 01127 // Copy this block to our destination bitmap 01128 // pNextStrip should be pointing at the next place to copy the data to 01129 memcpy(pNextStrip, pBitInfo, ChunkSize); 01130 } 01131 else 01132 { 01133 ChunkSize = BitsSize - Position; 01134 // Copy this block to our destination bitmap 01135 // pNextStrip should be pointing at the next place to copy the data to 01136 memcpy(pNextStrip, pBitInfo, ChunkSize); 01137 } 01138 01139 // Increment our counters/pointers 01140 Position+=ChunkSize; 01141 pBitInfo+=ChunkSize; 01142 pNextStrip += ChunkSize; 01143 // Progress bar started with height of bitmap 01144 ContinueSlowJob( (INT32)(ProgressOffset + (Height * Position)/BitsSize) ); 01145 //ContinueSlowJob( (INT32)((CurrentExportSize * Position)/BitsSize) ); 01146 } 01147 } 01148 } 01149 } 01150 01151 // If present, get rid of our export function 01152 if (DoConvert) 01153 { 01154 delete DoConvert; 01155 DoConvert = NULL; 01156 } 01157 01158 CCFree( Buffer ); 01159 01160 HeightWritten += Height; // remember we wrote this lot 01161 01162 return TRUE; 01163 }
|
|
Definition at line 178 of file outptpng.h. |
|
Definition at line 181 of file outptpng.h. |
|
Definition at line 162 of file outptpng.h. |
|
Definition at line 161 of file outptpng.h. |
|
Definition at line 173 of file outptpng.h. |
|
Definition at line 167 of file outptpng.h. |
|
Definition at line 179 of file outptpng.h. |
|
Definition at line 175 of file outptpng.h. |
|
Definition at line 163 of file outptpng.h. |
|
Definition at line 166 of file outptpng.h. |
|
Definition at line 176 of file outptpng.h. |
|
Definition at line 172 of file outptpng.h. |
|
Definition at line 183 of file outptpng.h. |