1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project//------------------------------------- 2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project// PNGFILE.C -- Image File Functions 3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project//------------------------------------- 4893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott// Copyright 2000, Willem van Schaik. 6a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott// 7a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott// This code is released under the libpng license. 8a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott// For conditions of distribution and use, see the disclaimer 9a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott// and license in png.h 10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <windows.h> 12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <commdlg.h> 13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdio.h> 14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdlib.h> 15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "png.h" 17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "pngfile.h" 18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "cexcept.h" 19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefine_exception_type(const char *); 21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectextern struct exception_context the_exception_context[1]; 22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstruct exception_context the_exception_context[1]; 23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_const_charp msg; 24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic OPENFILENAME ofn; 26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic png_structp png_ptr = NULL; 28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic png_infop info_ptr = NULL; 29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project// cexcept interface 32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void 34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_cexcept_error(png_structp png_ptr, png_const_charp msg) 35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if(png_ptr) 37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ; 38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef PNG_NO_CONSOLE_IO 39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, "libpng error: %s\n", msg); 40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Throw msg; 43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project// Windows open-file functions 47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PngFileInitialize (HWND hwnd) 49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project static TCHAR szFilter[] = TEXT ("PNG Files (*.PNG)\0*.png\0") 51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project TEXT ("All Files (*.*)\0*.*\0\0"); 52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lStructSize = sizeof (OPENFILENAME); 54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.hwndOwner = hwnd; 55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.hInstance = NULL; 56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrFilter = szFilter; 57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrCustomFilter = NULL; 58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.nMaxCustFilter = 0; 59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.nFilterIndex = 0; 60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrFile = NULL; // Set in Open and Close functions 61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.nMaxFile = MAX_PATH; 62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrFileTitle = NULL; // Set in Open and Close functions 63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.nMaxFileTitle = MAX_PATH; 64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrInitialDir = NULL; 65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrTitle = NULL; 66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.Flags = 0; // Set in Open and Close functions 67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.nFileOffset = 0; 68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.nFileExtension = 0; 69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrDefExt = TEXT ("png"); 70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lCustData = 0; 71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpfnHook = NULL; 72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpTemplateName = NULL; 73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) 76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.hwndOwner = hwnd; 78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrFile = pstrFileName; 79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrFileTitle = pstrTitleName; 80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.Flags = OFN_HIDEREADONLY; 81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return GetOpenFileName (&ofn); 83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) 86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.hwndOwner = hwnd; 88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrFile = pstrFileName; 89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.lpstrFileTitle = pstrTitleName; 90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; 91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return GetSaveFileName (&ofn); 93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project// PNG image handler functions 96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, 98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor) 99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project static FILE *pfFile; 101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte pbSig[8]; 102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int iBitDepth; 103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int iColorType; 104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project double dGamma; 105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color_16 *pBackground; 106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 ulChannels; 107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 ulRowBytes; 108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte *pbImageData = *ppbImageData; 109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project static png_byte **ppbRowPointers = NULL; 110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // open the PNG input file 113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!pstrFileName) 115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *ppbImageData = pbImageData = NULL; 117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(pfFile = fopen(pstrFileName, "rb"))) 121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *ppbImageData = pbImageData = NULL; 123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // first check the eight byte PNG signature 127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fread(pbSig, 1, 8, pfFile); 1295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_sig_cmp(pbSig, 0, 8)) 130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *ppbImageData = pbImageData = NULL; 132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // create the two png(-info) structures 136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, 138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); 139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!png_ptr) 140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *ppbImageData = pbImageData = NULL; 142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr = png_create_info_struct(png_ptr); 146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!info_ptr) 147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_read_struct(&png_ptr, NULL, NULL); 149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *ppbImageData = pbImageData = NULL; 150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Try 154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // initialize the png structure 157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_NO_STDIO) 159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_init_io(png_ptr, pfFile); 160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data); 162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_sig_bytes(png_ptr, 8); 165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // read all PNG info up to image data 167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_info(png_ptr, info_ptr); 169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // get width, height, bit-depth and color-type 171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, 173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project &iColorType, NULL, NULL, NULL); 174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // expand images of all color-type and bit-depth to 3x8 bit RGB images 176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // let the library process things like alpha, transparency, background 177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (iBitDepth == 16) 179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_strip_16(png_ptr); 180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (iColorType == PNG_COLOR_TYPE_PALETTE) 181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_expand(png_ptr); 182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (iBitDepth < 8) 183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_expand(png_ptr); 184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_expand(png_ptr); 186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (iColorType == PNG_COLOR_TYPE_GRAY || 187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project iColorType == PNG_COLOR_TYPE_GRAY_ALPHA) 188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_gray_to_rgb(png_ptr); 189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // set the background color to draw transparent and alpha images over. 191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_get_bKGD(png_ptr, info_ptr, &pBackground)) 192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); 194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pBkgColor->red = (byte) pBackground->red; 195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pBkgColor->green = (byte) pBackground->green; 196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pBkgColor->blue = (byte) pBackground->blue; 197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pBkgColor = NULL; 201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // if required set gamma conversion 204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_get_gAMA(png_ptr, info_ptr, &dGamma)) 205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_gamma(png_ptr, (double) 2.2, dGamma); 206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // after the transformations have been registered update info_ptr data 208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_update_info(png_ptr, info_ptr); 210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // get again width, height and the new bit-depth and color-type 212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, 214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project &iColorType, NULL, NULL, NULL); 215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // row_bytes is the width x number of channels 218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ulRowBytes = png_get_rowbytes(png_ptr, info_ptr); 220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ulChannels = png_get_channels(png_ptr, info_ptr); 221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *piChannels = ulChannels; 223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // now we can allocate memory to store the image 225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (pbImageData) 227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free (pbImageData); 229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pbImageData = NULL; 230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight) 232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * sizeof(png_byte))) == NULL) 233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Visual PNG: out of memory"); 235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *ppbImageData = pbImageData; 237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // and allocate memory for an array of row-pointers 239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((ppbRowPointers = (png_bytepp) malloc((*piHeight) 241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * sizeof(png_bytep))) == NULL) 242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Visual PNG: out of memory"); 244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // set the individual row-pointers to point at the correct offsets 247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < (*piHeight); i++) 249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ppbRowPointers[i] = pbImageData + i * ulRowBytes; 250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // now we can go ahead and just read the whole image 252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_image(png_ptr, ppbRowPointers); 254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // read the additional chunks in the PNG file (not really needed) 256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_end(png_ptr, NULL); 258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // and we're done 260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free (ppbRowPointers); 262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ppbRowPointers = NULL; 263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // yepp, done 265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Catch (msg) 268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *ppbImageData = pbImageData = NULL; 272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if(ppbRowPointers) 274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free (ppbRowPointers); 275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose(pfFile); 277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose (pfFile); 282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return TRUE; 284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData, 288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int iWidth, int iHeight, png_color bkgColor) 289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project const int ciBitDepth = 8; 291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project const int ciChannels = 3; 292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project static FILE *pfFile; 294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 ulRowBytes; 295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project static png_byte **ppbRowPointers = NULL; 296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // open the PNG output file 299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!pstrFileName) 301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(pfFile = fopen(pstrFileName, "wb"))) 304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // prepare the standard PNG structures 307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, 309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); 310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!png_ptr) 311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose(pfFile); 313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr = png_create_info_struct(png_ptr); 317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!info_ptr) { 318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose(pfFile); 319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, (png_infopp) NULL); 320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Try 324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // initialize the png structure 326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_NO_STDIO) 328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_init_io(png_ptr, pfFile); 329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush); 331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // we're going to write a very simple 3x8 bit RGB image 334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth, 336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, 337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_FILTER_TYPE_BASE); 338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // write the file header information 340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_info(png_ptr, info_ptr); 342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // swap the BGR pixels in the DiData structure to RGB 344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_bgr(png_ptr); 346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // row_bytes is the width x number of channels 348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ulRowBytes = iWidth * ciChannels; 350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // we can allocate memory for an array of row-pointers 352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL) 354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Throw "Visualpng: Out of memory"; 355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // set the individual row-pointers to point at the correct offsets 357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < iHeight; i++) 359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2); 360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // write out the entire image data in one call 362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_image (png_ptr, ppbRowPointers); 364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // write the additional chunks to the PNG file (not really needed) 366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_end(png_ptr, info_ptr); 368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // and we're done 370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free (ppbRowPointers); 372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ppbRowPointers = NULL; 373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // clean up after the write, and free any memory allocated 375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, (png_infopp) NULL); 377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project // yepp, done 379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Catch (msg) 382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, (png_infopp) NULL); 384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if(ppbRowPointers) 386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project free (ppbRowPointers); 387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose(pfFile); 389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return FALSE; 391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fclose (pfFile); 394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return TRUE; 396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_NO_STDIO 399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void 401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_data(png_structp png_ptr, png_bytep data, png_size_t length) 402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t check; 404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* fread() returns 0 on error, so it is OK to store this in a png_size_t 406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * instead of an int, which is what fread() actually returns. 407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project check = (png_size_t)fread(data, (png_size_t)1, length, 409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (FILE *)png_ptr->io_ptr); 410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (check != length) 412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Read Error"); 414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void 418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_write_data(png_structp png_ptr, png_bytep data, png_size_t length) 419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 check; 421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); 423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (check != length) 424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Write Error"); 426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void 430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_flush(png_structp png_ptr) 431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project FILE *io_ptr; 433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); 434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (io_ptr != NULL) 435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fflush(io_ptr); 436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project//----------------- 441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project// end of source 442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project//----------------- 443