void PLSubBmp::Create(int Width, int Height, const PLPixelFormat &pf, PLBYTE *pBits, int Stride ) { if (m_pLineArray) { if (Width != GetWidth() || Height != GetHeight() || pf != GetPixelFormat()) { freeMembers(); } } if (!m_pLineArray) { // freeMembers sets m_pLineArray to 0. if (pf.GetBitsPerPixel() <= 8) m_pClrTab = new PLPixel32[(int)(1 << pf.GetBitsPerPixel())]; else m_pClrTab = NULL; initLocals (Width, Height, pf); if (pf.GetBitsPerPixel() <= 8) SetGrayPalette (); m_pLineArray = new PLBYTE * [m_Size.y]; } PLBYTE * pCurLine = m_pLineArray[0]; for (int y=0; y<m_Size.y; y++) { m_pLineArray[y] = pBits; pBits += Stride; } PLASSERT_VALID(this); }
void PLDIBSection::internalCreate ( PLLONG Width, PLLONG Height, const PLPixelFormat& pf ) // Create a new empty DIBSection. // Assumes that no memory is allocated before the call. { #ifdef MAX_BITMAP_SIZE if (GetMemNeeded (Width, Height, pf.GetBitsPerPixel()) > MAX_BITMAP_SIZE) throw PLTextException(PL_ERRDIB_TOO_LARGE, "Bitmap size too large.\n"); #endif int MemNeeded = sizeof (BITMAPINFOHEADER); if (pf.GetBitsPerPixel() <= 8) { // Color table exists MemNeeded += (1 << pf.GetBitsPerPixel())*sizeof (RGBQUAD); } m_pBMI = (BITMAPINFOHEADER*) malloc (MemNeeded); // out of memory? if (!m_pBMI) throw (PLTextException (PL_ERRNO_MEMORY, "Out of memory creating bitmap.")); // Fill in the header info. m_pBMI->biSize = sizeof(BITMAPINFOHEADER); m_pBMI->biWidth = Width; m_pBMI->biHeight = Height; m_pBMI->biPlanes = 1; m_pBMI->biBitCount = pf.GetBitsPerPixel(); m_pBMI->biCompression = BI_RGB; // No compression m_pBMI->biSizeImage = 0; m_pBMI->biXPelsPerMeter = 0; m_pBMI->biYPelsPerMeter = 0; m_pBMI->biClrUsed = 0; // Always use the whole palette. m_pBMI->biClrImportant = 0; // Create DIB section in shared memory m_hBitmap = CreateDIBSection (NULL, (BITMAPINFO *)m_pBMI, DIB_RGB_COLORS, (void **)&m_pBits, 0, 0l); if (!m_hBitmap) throw (PLTextException (PL_ERRNO_MEMORY, "Out of memory creating bitmap.")); // Set color table pointer & pointer to bits. initPointers (); initLocals (Width, Height, pf); PLASSERT_VALID (this); }
void PLPNGDecoder::Open(PLDataSource *pDataSrc) { png_uint_32 width, height; m_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, user_error_fn, user_warning_fn); PLASSERT(m_png_ptr); m_info_ptr = png_create_info_struct(m_png_ptr); PLASSERT(m_info_ptr); png_set_read_fn(m_png_ptr, (void*)pDataSrc, my_read_data); /* The call to png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). */ png_read_info(m_png_ptr, m_info_ptr); #ifdef DUMP_PNG_DATA debugLog("%s", toString(*m_png_ptr).cstr()); #endif png_get_IHDR(m_png_ptr, m_info_ptr, &width, &height, &m_bit_depth ,&m_color_type, NULL, NULL, NULL); if( (m_color_type != PNG_COLOR_TYPE_RGB_ALPHA) && (m_color_type != PNG_COLOR_TYPE_GRAY_ALPHA) && ((m_color_type != PNG_COLOR_TYPE_RGB) || (m_bit_depth < 16)) ) { #ifdef PNG_READ_16_TO_8_SUPPORTED if(m_bit_depth == 16) { #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED png_set_scale_16(png_ptr); #else png_set_strip_16(png_ptr); #endif } #endif if(m_color_type == PNG_COLOR_TYPE_PALETTE) { png_set_expand(m_png_ptr); } if(m_bit_depth < 8) { png_set_expand(m_png_ptr); } if(png_get_valid(m_png_ptr, m_info_ptr, PNG_INFO_tRNS)) { png_set_expand(m_png_ptr); } if((m_color_type == PNG_COLOR_TYPE_GRAY) || (m_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) { png_set_gray_to_rgb(m_png_ptr); } /* set the background color to draw transparent and alpha images over */ png_color_16 *pBackground; png_color bkgColor = {127, 127, 127}; if(png_get_bKGD(m_png_ptr, m_info_ptr, &pBackground)) { png_set_background(m_png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); bkgColor.red = (png_byte)pBackground->red; bkgColor.green = (png_byte)pBackground->green; bkgColor.blue = (png_byte)pBackground->blue; #ifdef DUMP_PNG_DATA debugLog(" Background : (%d,%d,%d)\n", bkgColor.red, bkgColor.green, bkgColor.blue); #endif } /* if required set gamma conversion */ double dGamma; if(png_get_gAMA(m_png_ptr, m_info_ptr, &dGamma)) { png_set_gamma(m_png_ptr, (double)2.2, dGamma); } /* after the transformations are registered, update info_ptr data */ png_read_update_info(m_png_ptr, m_info_ptr); png_get_IHDR(m_png_ptr, m_info_ptr, &width, &height, &m_bit_depth ,&m_color_type, NULL, NULL, NULL); } PLPixelFormat pf; switch(m_color_type) { case PNG_COLOR_TYPE_RGB: pf = PLPixelFormat::R8G8B8; break; case PNG_COLOR_TYPE_RGB_ALPHA: pf = PLPixelFormat::A8R8G8B8; break; case PNG_COLOR_TYPE_GRAY: pf = PLPixelFormat::L8; break; case PNG_COLOR_TYPE_GRAY_ALPHA: png_set_gray_to_rgb(m_png_ptr); png_set_expand(m_png_ptr); pf = PLPixelFormat::A8R8G8B8; break; case PNG_COLOR_TYPE_PALETTE: if(m_bit_depth != 16) { pf = PLPixelFormat::I8; } else { // 16-bit palette image png_set_expand(m_png_ptr); pf = PLPixelFormat::R8G8B8; } break; } if((pf.GetBitsPerPixel() == 32) || (pf.GetBitsPerPixel() == 24)) { png_set_bgr(m_png_ptr); } SetBmpInfo(PLPoint(width, height), PLPoint(0,0), pf); png_uint_32 XRes, YRes; int UnitType; png_get_pHYs(m_png_ptr, m_info_ptr, &XRes, &YRes, &UnitType); if(UnitType == PNG_RESOLUTION_METER) { m_Resolution = PLPoint(int (XRes/39.37f+0.5), int (YRes/39.37f+0.5)); } }