LPBYTE CCeXDib::GetBits() { if (m_hDib) return ((LPBYTE)m_hDib + *(LPDWORD)m_hDib + GetPaletteSize()); return NULL; } // End of GetBits
void CxDib::SetGrayPalette() { if ((hDib==NULL)||(m_nColors==0)) return; RGBQUAD pal[256]; RGBQUAD* ppal; BYTE* iDst; int ni; ppal=(RGBQUAD*)&pal[0]; iDst = (BYTE*)(hDib) + sizeof(BITMAPINFOHEADER); for (ni=0;ni<m_nColors;ni++){ pal[ni]=RGB2RGBQUAD(RGB(ni,ni,ni));} pal[0]=RGB2RGBQUAD(RGB(0,0,0)); pal[m_nColors-1]=RGB2RGBQUAD(RGB(255,255,255)); memcpy(iDst,ppal,GetPaletteSize()); return; }
BOOL CCeXDib::WriteBMP(LPCTSTR bmpFileName) { BITMAPFILEHEADER hdr; HANDLE hFile; DWORD nByteWrite; if (*bmpFileName == _T('\0') || m_hDib == 0) return 0; hFile=CreateFile( // open if exist ini file bmpFileName, // pointer to name of the file GENERIC_WRITE, // access mode 0, // share mode NULL, // pointer to security descriptor CREATE_ALWAYS, // how to create FILE_ATTRIBUTE_NORMAL, // file attributes NULL // handle to file with attributes to copy ); if (hFile == INVALID_HANDLE_VALUE) return FALSE; // Fill in the fields of the file header hdr.bfType = BFT_BITMAP; hdr.bfSize = GetSize() + sizeof(BITMAPFILEHEADER); hdr.bfReserved1 = hdr.bfReserved2 = 0; hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER)+ m_bi.biSize + GetPaletteSize(); // Write the file header WriteFile( // write ini (sync mode <-> no overlapped) hFile, // handle of file to write (LPSTR) &hdr, // address of buffer that contains data sizeof(BITMAPFILEHEADER), // number of bytes to write &nByteWrite, // address of number of bytes written NULL // address of structure for data ); // Write the DIB header and the bits WriteFile( // write ini (sync mode <-> no overlapped) hFile, // handle of file to write (LPSTR) m_hDib, // address of buffer that contains data GetSize(), // number of bytes to write &nByteWrite, // address of number of bytes written NULL // address of structure for data ); CloseHandle(hFile); // free file handle return TRUE; } // End of WriteBMP
bool CxImageBMP::Encode(CxFile * hFile) { if (hFile==NULL) return false; BITMAPFILEHEADER hdr; hdr.bfType = 0x4d42; // 'BM' WINDOWS_BITMAP_SIGNATURE hdr.bfSize = GetSize() + sizeof(BITMAPFILEHEADER); hdr.bfReserved1 = hdr.bfReserved2 = 0; hdr.bfOffBits = (DWORD) sizeof(hdr) + head.biSize + GetPaletteSize(); //copy attributes memcpy(pDib,&head,sizeof(BITMAPINFOHEADER)); // Write the file header hFile->Write(&hdr,sizeof(BITMAPFILEHEADER),1); // Write the DIB header and the pixels hFile->Write(pDib,GetSize(),1); return true; }
void CCeXDib::SetGrayPalette() { RGBQUAD pal[256]; RGBQUAD* ppal; LPBYTE iDst; int ni; if (m_hDib == NULL || m_wColors == 0) return; ppal = (RGBQUAD*)&pal[0]; iDst = (LPBYTE)(m_hDib) + sizeof(BITMAPINFOHEADER); for (ni = 0; ni < m_wColors; ni++) { pal[ni] = RGB2RGBQUAD(RGB(ni,ni,ni)); } // for pal[0] = RGB2RGBQUAD(RGB(0,0,0)); pal[m_wColors-1] = RGB2RGBQUAD(RGB(255,255,255)); memcpy(iDst, ppal, GetPaletteSize()); } // End of SetGrayPalette
BOOL CImageTIFF::Write(FILE* stream) { //prepare the palette struct RGBQUAD pal[256]; if (GetPalette()){ BYTE b; memcpy(pal,GetPalette(),GetPaletteSize()); for(WORD a=0;a<m_header.biClrUsed;a++){ //swap blue and red components b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b; } } TIFF *m_tif=NULL; // = (TIFF *)new(byte[512]); uint32 height=m_header.biHeight; uint32 width=m_header.biWidth; // uint32 rowsperstrip = (uint32) -1; uint16 bitspersample=m_header.biBitCount; uint16 samplesperpixel; uint16 photometric; uint16 compression; uint16 pitch; int line; uint32 x, y; samplesperpixel = ((bitspersample == 24) || (bitspersample == 32)) ? 3 : 1; photometric = (samplesperpixel==3) ? PHOTOMETRIC_RGB : PHOTOMETRIC_PALETTE; line = CalculateLine(width, bitspersample * samplesperpixel); pitch = CalculatePitch(line); m_tif=TIFFOpenEx(stream, "wb"); if (m_tif==NULL) return FALSE; // handle standard width/height/bpp stuff TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height); TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, ((bitspersample == 32) ? 24 : bitspersample) / samplesperpixel); TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); // single image plane TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, 1); // TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(m_tif, rowsperstrip)); // handle metrics TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, 72.0); TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, 72.0); // multi-paging // if (page >= 0) { // char page_number[20]; // sprintf(page_number, "Page %d", page); // // TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE); // TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page); // TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number); // } else { TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0); // } // palettes (image colormaps are automatically scaled to 16-bits) if (photometric == PHOTOMETRIC_PALETTE) { uint16 *r, *g, *b; r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256); g = r + 256; b = g + 256; for (int i = 255; i >= 0; i--) { b[i] = SCALE((uint16)pal[i].rgbRed); g[i] = SCALE((uint16)pal[i].rgbGreen); r[i] = SCALE((uint16)pal[i].rgbBlue); } TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b); _TIFFfree(r); } // compression switch(bitspersample) { case 1 : compression = COMPRESSION_CCITTFAX4; break; case 8 : case 24 : case 32 : compression = COMPRESSION_PACKBITS; break; default : compression = COMPRESSION_NONE; break; } TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression); // read the DIB lines from bottom to top // and save them in the TIF // ------------------------------------- BYTE *bits; switch(bitspersample) { case 1 : case 4 : case 8 : { for (y = 0; y < height; y++) { bits= m_info.pImage + (height - y - 1)*m_info.dwEffWidth; TIFFWriteScanline(m_tif,bits, y, 0); } break; } case 24: case 32 : { BYTE *buffer = (BYTE *)malloc(m_info.dwEffWidth); for (y = 0; y < height; y++) { // get a pointer to the scanline memcpy(buffer, m_info.pImage + (height - y - 1)*m_info.dwEffWidth, m_info.dwEffWidth); // TIFFs store color data RGB instead of BGR BYTE *pBuf = buffer; for (x = 0; x < width; x++) { BYTE tmp = pBuf[0]; pBuf[0] = pBuf[2]; pBuf[2] = tmp; pBuf += 3; } // write the scanline to disc TIFFWriteScanline(m_tif, buffer, y, 0); } free(buffer); break; } } TIFFClose(m_tif); return true; }
DWORD CCeXDib::GetSize() { return m_bi.biSize + m_bi.biSizeImage + GetPaletteSize(); } // End of GetSize
long CxDib::GetSize() { return m_bi.biSize + m_bi.biSizeImage + GetPaletteSize(); }
BYTE* CxDib::GetBits() { if (hDib) return ((BYTE*)hDib + *(LPDWORD)hDib + GetPaletteSize()); return NULL; }
bool CxImageTIF::EncodeBody(TIFF *m_tif, bool multipage, int page, int pagecount) { uint32 height=head.biHeight; uint32 width=head.biWidth; uint16 bitcount=head.biBitCount; uint16 bitspersample; uint16 samplesperpixel; uint16 photometric=0; uint16 compression; // uint16 pitch; // int line; uint32 x, y; samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (BYTE)3 : (BYTE)1; #if CXIMAGE_SUPPORT_ALPHA if (bitcount==24 && AlphaIsValid()) { bitcount=32; samplesperpixel=4; } #endif //CXIMAGE_SUPPORT_ALPHA bitspersample = bitcount / samplesperpixel; //set the PHOTOMETRIC tag RGBQUAD *rgb = GetPalette(); switch (bitcount) { case 1: if (CompareColors(&rgb[0],&rgb[1])<0) { /* <abe> some viewers do not handle PHOTOMETRIC_MINISBLACK: * let's transform the image in PHOTOMETRIC_MINISWHITE */ //invert the colors RGBQUAD tempRGB=GetPaletteColor(0); SetPaletteColor(0,GetPaletteColor(1)); SetPaletteColor(1,tempRGB); //invert the pixels BYTE *iSrc=info.pImage; for (unsigned long i=0;i<head.biSizeImage;i++){ *iSrc=(BYTE)~(*(iSrc)); iSrc++; } photometric = PHOTOMETRIC_MINISWHITE; //photometric = PHOTOMETRIC_MINISBLACK; } else { photometric = PHOTOMETRIC_MINISWHITE; } break; case 4: // Check if the DIB has a color or a greyscale palette case 8: photometric = PHOTOMETRIC_MINISBLACK; //default to gray scale for (x = 0; x < head.biClrUsed; x++) { if ((rgb->rgbRed != x)||(rgb->rgbRed != rgb->rgbGreen)||(rgb->rgbRed != rgb->rgbBlue)){ photometric = PHOTOMETRIC_PALETTE; break; } rgb++; } break; case 24: case 32: photometric = PHOTOMETRIC_RGB; break; } #if CXIMAGE_SUPPORT_ALPHA if (AlphaIsValid() && bitcount==8) samplesperpixel=2; //8bpp + alpha layer #endif //CXIMAGE_SUPPORT_ALPHA // line = CalculateLine(width, bitspersample * samplesperpixel); // pitch = (uint16)CalculatePitch(line); //prepare the palette struct RGBQUAD pal[256]; if (GetPalette()){ BYTE b; memcpy(pal,GetPalette(),GetPaletteSize()); for(WORD a=0;a<head.biClrUsed;a++){ //swap blue and red components b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b; } } // handle standard width/height/bpp stuff TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height); TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, bitspersample); TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); // single image plane TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); uint32 rowsperstrip = TIFFDefaultStripSize(m_tif, (uint32) -1); //<REC> gives better compression TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); // handle metrics TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, (float)info.xDPI); TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, (float)info.yDPI); // TIFFSetField(m_tif, TIFFTAG_XPOSITION, (float)info.xOffset); // TIFFSetField(m_tif, TIFFTAG_YPOSITION, (float)info.yOffset); // multi-paging - Thanks to Abe <God(dot)bless(at)marihuana(dot)com> if (multipage) { char page_number[20]; sprintf(page_number, "Page %d", page); TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE); TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page,pagecount); TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number); } else { TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0); } // palettes (image colormaps are automatically scaled to 16-bits) if (photometric == PHOTOMETRIC_PALETTE) { uint16 *r, *g, *b; r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256); g = r + 256; b = g + 256; for (int i = 255; i >= 0; i--) { b[i] = (uint16)SCALE((uint16)pal[i].rgbRed); g[i] = (uint16)SCALE((uint16)pal[i].rgbGreen); r[i] = (uint16)SCALE((uint16)pal[i].rgbBlue); } TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b); _TIFFfree(r); } // compression if (GetCodecOption(CXIMAGE_FORMAT_TIF)) { compression = (WORD)GetCodecOption(CXIMAGE_FORMAT_TIF); } else { switch (bitcount) { case 1 : compression = COMPRESSION_CCITTFAX4; break; case 4 : case 8 : compression = COMPRESSION_LZW; break; case 24 : case 32 : compression = COMPRESSION_JPEG; break; default : compression = COMPRESSION_NONE; break; } } TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression); switch (compression) { case COMPRESSION_JPEG: TIFFSetField(m_tif, TIFFTAG_JPEGQUALITY, info.nQuality); TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, ((7+rowsperstrip)>>3)<<3); break; case COMPRESSION_LZW: if (bitcount>=8) TIFFSetField(m_tif, TIFFTAG_PREDICTOR, 2); break; } // read the DIB lines from bottom to top and save them in the TIF BYTE *bits; switch(bitcount) { case 1 : case 4 : case 8 : { if (samplesperpixel==1){ for (y = 0; y < height; y++) { bits= info.pImage + (height - y - 1)*info.dwEffWidth; if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) return false; } } #if CXIMAGE_SUPPORT_ALPHA else { //8bpp + alpha layer bits = (BYTE*)malloc(2*width); if (!bits) return false; for (y = 0; y < height; y++) { for (x=0;x<width;x++){ bits[2*x]=GetPixelIndex(x,height - y - 1); bits[2*x+1]=AlphaGet(x,height - y - 1); } if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) { free(bits); return false; } } free(bits); } #endif //CXIMAGE_SUPPORT_ALPHA break; } case 24: { BYTE *buffer = (BYTE *)malloc(info.dwEffWidth); if (!buffer) return false; for (y = 0; y < height; y++) { // get a pointer to the scanline memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth); // TIFFs store color data RGB instead of BGR BYTE *pBuf = buffer; for (x = 0; x < width; x++) { BYTE tmp = pBuf[0]; pBuf[0] = pBuf[2]; pBuf[2] = tmp; pBuf += 3; } // write the scanline to disc if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){ free(buffer); return false; } } free(buffer); break; } case 32 : { #if CXIMAGE_SUPPORT_ALPHA BYTE *buffer = (BYTE *)malloc((info.dwEffWidth*4)/3); if (!buffer) return false; for (y = 0; y < height; y++) { // get a pointer to the scanline memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth); // TIFFs store color data RGB instead of BGR BYTE *pSrc = buffer + 3 * width; BYTE *pDst = buffer + 4 * width; for (x = 0; x < width; x++) { pDst-=4; pSrc-=3; pDst[3] = AlphaGet(width-x-1,height-y-1); pDst[2] = pSrc[0]; pDst[1] = pSrc[1]; pDst[0] = pSrc[2]; } // write the scanline to disc if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){ free(buffer); return false; } } free(buffer); #endif //CXIMAGE_SUPPORT_ALPHA break; } } return true; }