//--------------------------------------------------------------------------// //--------------------------------------------------------------------------// void CAGSymImage::LoadDIB(const BITMAPINFOHEADER* pHdr, const BYTE* pBits) { Free(); if (pHdr->biCompression == BI_RGB && (pHdr->biBitCount == 1 || pHdr->biBitCount == 4 || pHdr->biBitCount == 8 || pHdr->biBitCount == 24)) { BITMAPINFOHEADER bi; bi = *pHdr; bi.biCompression = BI_RGB; if (!bi.biSizeImage) bi.biSizeImage = DibSizeImage(&bi); if (!bi.biClrUsed) bi.biClrUsed = DibNumColors(&bi); if (m_pDIB = (BITMAPINFOHEADER*)malloc(DibSize(&bi))) { *m_pDIB = bi; if (bi.biClrUsed) memcpy((void*)DibColors(m_pDIB), (void*)DibColors(pHdr), DibPaletteSize(pHdr)); BYTE* pNewBits = (BYTE*)DibPtr(m_pDIB); const BYTE* pSrcBits; if (pBits) pSrcBits = pBits; else pSrcBits = (BYTE*)(DibColors(pHdr) + bi.biClrUsed); memcpy(pNewBits, pSrcBits, bi.biSizeImage); } } }
BOOL FAR PASCAL DibClear(PDIB pdibDst, LPVOID pbitsDst, BYTE value) { WORD selDst; DWORD offDst; if ((pdibDst == NULL) || (pbitsDst == NULL)) return FALSE; if ((long)pbitsDst & 3) return FALSE; // we must be dword aligned selDst = HIWORD(pbitsDst); offDst = LOWORD(pbitsDst); ClearMem32(selDst, offDst, DibSizeImage(pdibDst), value); return TRUE; }
HGLOBAL CPng::PNGToDIB(png_structp png_ptr, png_infop info_ptr) { //Read the image png_read_info(png_ptr, info_ptr); int nBitDepth = 0; int nColorType = 0; png_uint_32 width = 0; png_uint_32 height = 0; png_get_IHDR(png_ptr, info_ptr, &width, &height, &nBitDepth, &nColorType, NULL, NULL, NULL); IMAGE img; img.width = (LONG)width; img.height = (LONG)height; //Determine the type of format if (nColorType==PNG_COLOR_TYPE_RGB || nColorType==PNG_COLOR_TYPE_RGB_ALPHA) { img.pixdepth = 24; // nBitDepth 8, 16 img.palnum = 0; } else { switch(nBitDepth) // bit depths 1, 2, 4, 8, 16 { case 2: img.pixdepth = 4; break; case 16: img.pixdepth = 8; break; default: img.pixdepth = nBitDepth; } img.palnum = 1 << img.pixdepth; } //Allocate the image struct that will be used to transport file info if (!AllocImageStruct(&img)) { longjmp(png_ptr->jmpbuf, 1); } //Not sure if we can take advantage of this info in a BMP, thus remove it. if (nColorType & PNG_COLOR_MASK_ALPHA) png_set_strip_alpha(png_ptr); //Set user transform function to deal with a Bitdepth of 2 if (nBitDepth == 2) { png_set_user_transform_info(png_ptr, NULL, 4, 1); png_set_read_user_transform_fn(png_ptr, ConvertTo4BitsPerPix); } //Tell libpng to strip 16 bit/color files down to 8 bits/color if (nBitDepth == 16) png_set_strip_16(png_ptr); if (nColorType==PNG_COLOR_TYPE_RGB || nColorType==PNG_COLOR_TYPE_RGB_ALPHA) { png_set_bgr(png_ptr); } png_read_update_info(png_ptr, info_ptr); //If palette, get it and fill our img struct if (img.palnum > 0) { if (nColorType == PNG_COLOR_TYPE_PALETTE) { png_colorp palette; int num_palette; png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); if (num_palette > (int)img.palnum) num_palette = img.palnum; memset(img.palette, 0, img.palnum * sizeof(png_color)); memcpy(img.palette, palette, num_palette * sizeof(png_color)); } else { int depth = (nBitDepth == 16)? 8 : nBitDepth ; png_build_grayscale_palette(depth, img.palette); } } png_read_image(png_ptr, img.rowptr); png_infop end_info = NULL; png_read_end(png_ptr, end_info); // Alloc the buffer to be big enough to hold all the bits DWORD dwLen = (DWORD)sizeof(BITMAPINFOHEADER) + (img.palnum * sizeof(RGBQUAD)) + img.imgbytes; // Allocate enough memory to hold the entire DIB HGLOBAL hMemory = ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, dwLen); if (!hMemory) return NULL; //Begin filling out DIB info BITMAPINFOHEADER* pDib = (BITMAPINFOHEADER*)::GlobalLock(hMemory); if (!pDib) { ::GlobalFree(hMemory); return NULL; } ::ZeroMemory(pDib, dwLen); pDib->biSize = sizeof(BITMAPINFOHEADER); pDib->biWidth = (DWORD)img.width; pDib->biHeight = (DWORD)img.height; pDib->biPlanes = 1; pDib->biCompression = BI_RGB; pDib->biXPelsPerMeter = 3937; // 100 pixels/inch pDib->biYPelsPerMeter = 3937; pDib->biSizeImage = img.imgbytes; pDib->biBitCount = img.pixdepth; pDib->biClrUsed = img.palnum; if (pDib->biBitCount >= 16) pDib->biBitCount = 24; if (pDib->biClrUsed) { RGBQUAD* pRgb = DibColors(pDib); BYTE rgbq[RGBQUAD_SIZE]; PALETTE* pal; UINT nIndex; memset(rgbq, 0, sizeof(rgbq)); for (pal = img.palette, nIndex = img.palnum ; nIndex > 0 ; nIndex--, pal++) { rgbq[RGBQ_RED] = pal->red; rgbq[RGBQ_GREEN] = pal->green; rgbq[RGBQ_BLUE] = pal->blue; rgbq[RGBQ_RESERVED] = 0; memcpy((LPVOID)pRgb, rgbq, sizeof(RGBQUAD)); pRgb++; } } memcpy(DibPtr(pDib), img.bmpbits, DibSizeImage(pDib)); FreeImageStruct(&img); ::GlobalUnlock(hMemory); return hMemory; }
PDIB DibReadBitmapInfo(int fh) { DWORD off; HANDLE hbi = NULL; int size; int i; int nNumColors; RGBQUAD FAR *pRgb; BITMAPINFOHEADER bi; BITMAPCOREHEADER bc; BITMAPFILEHEADER bf; PDIB pdib; if (fh == -1) return NULL; off = lseek(fh,0L,SEEK_CUR); if (sizeof(bf) != read(fh,(LPSTR)&bf,sizeof(bf))) return FALSE; /* * do we have a RC HEADER? */ if (bf.bfType != BFT_BITMAP) { bf.bfOffBits = 0L; lseek(fh,off,SEEK_SET); } if (sizeof(bi) != read(fh,(LPSTR)&bi,sizeof(bi))) return FALSE; /* * what type of bitmap info is this? */ switch (size = (int)bi.biSize) { default: case sizeof(BITMAPINFOHEADER): break; case sizeof(BITMAPCOREHEADER): bc = *(BITMAPCOREHEADER*)&bi; bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = (DWORD)bc.bcWidth; bi.biHeight = (DWORD)bc.bcHeight; bi.biPlanes = (UINT)bc.bcPlanes; bi.biBitCount = (UINT)bc.bcBitCount; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; lseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR); break; } nNumColors = DibNumColors(&bi); if (bi.biSizeImage == 0) bi.biSizeImage = DibSizeImage(&bi); if (bi.biClrUsed == 0) bi.biClrUsed = DibNumColors(&bi); pdib = (PDIB) malloc((LONG)bi.biSize + nNumColors * sizeof(RGBQUAD)); if (!pdib) return NULL; *pdib = bi; pRgb = DibColors(pdib); if (nNumColors == 0) { printf("Bitmap has no palette (24 bit)\n", NUM_COLORS, nNumColors); return NULL; } if (nNumColors != NUM_COLORS) { printf("Expecting %d color bitmap; found %d colors\n", NUM_COLORS, nNumColors); return NULL; } if (size == sizeof(BITMAPCOREHEADER)) { /* * convert a old color table (3 byte entries) to a new * color table (4 byte entries) */ read(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE)); for (i=nNumColors-1; i>=0; i--) { RGBQUAD rgb; rgb.rgbRed = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed; rgb.rgbBlue = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue; rgb.rgbGreen = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen; rgb.rgbReserved = (BYTE)0; pRgb[i] = rgb; } } else { read(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD)); } if (bf.bfOffBits != 0L) lseek(fh,off + bf.bfOffBits,SEEK_SET); return pdib; }