KernelBitmap *CDRBitmap::ConvertBitmap4(RIFFFile *RIFF, DWORD *Reference, CDRFilter *C) { // check various things ERROR3IF(RIFF->GetObjChunkType() != cdrT_bmp, "ConvertBitmap called for non-bitmap RIFF chunk"); ERROR3IF(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK, "ConvertBitmap called for a non-chunk RIFF object"); if(RIFF->GetObjSize() < sizeof(cdrfBitmapHeader4)) { // Empty 'if' statement // Anyone's guess if this was intended // Changed to this form to remove a compiler warning // Markn 19/3/99 } // get some data from the RIFF file cdrfBitmapHeader4 Hdr; // get the header from offset 0 if(!RIFF->GetChunkData((ADDR)&Hdr, sizeof(Hdr), 0)) return 0; // check the header... if((((Hdr.SizeX * Hdr.SizeY) / Hdr.Depth) + Hdr.ImageOffset - cdrfBitmapHeaderImageOffsetCorrect) > (DWORD)RIFF->GetObjSize() || Hdr.Depth < 1 || Hdr.Depth > 32) { TRACEUSER( "Ben", _T("Header in CDR bitmap doesn't check out\n")); return 0; } // store the reference TRACEUSER( "Ben", _T("Bitmap reference = %X\n"), Hdr.Reference); *Reference = Hdr.Reference; // find a plausible number of palette entries... INT32 NPaletteEntries = Hdr.NPaletteEntries; if(NPaletteEntries > (1 << Hdr.Depth)) NPaletteEntries = (1 << Hdr.Depth); if(NPaletteEntries < 0) NPaletteEntries = 0; // is it a greyscale type bitmap? BOOL Greyscale = FALSE; // if(Hdr.Depth <= 8 && Hdr.ImageType == cdrfBITMAPTYPE_GREYSCALE) // Greyscale = TRUE; // OK, create a bitmap... LPBYTE Image; LPBITMAPINFO ImageHeader; ImageHeader = AllocDIB(Hdr.SizeX, Hdr.SizeY, Hdr.Depth, &Image); if(ImageHeader == 0) return 0; // right then, sort out that there palette if we really want to if(Hdr.Depth <= 8) { if(Greyscale) { // it's a greyscale image - create a nice palette UINT32 Entries = 1 << Hdr.Depth; UINT32 Inc = 256 / Entries; UINT32 Value = 0; UINT32 l; for(l = 0; l < Entries; l++) { ImageHeader->bmiColors[l].rgbRed = Value; ImageHeader->bmiColors[l].rgbGreen = Value; ImageHeader->bmiColors[l].rgbBlue = Value; ImageHeader->bmiColors[l].rgbReserved = 0; Value += Inc; } } else { // it's a colour image - load it's palette from the file // load the palette data into the palette in the created bitmap if(!RIFF->GetChunkData((ADDR)ImageHeader->bmiColors, sizeof(cdrfBitmapPaletteEntry4) * NPaletteEntries, sizeof(cdrfBitmapHeader4))) { FreeDIB(ImageHeader, Image); return 0; } } } // work out the scanline lengths (aligns to 4 bytes) INT32 RawScanlineLength = Hdr.SizeX * Hdr.Depth; // in bits INT32 ScanlineLength = ((RawScanlineLength + 31) / 32) * 4; // set up offsets of current line INT32 SourceOffset; if(Greyscale) { SourceOffset = cdrfBitmapGreyscaleImageStart; } else { SourceOffset = sizeof(cdrfBitmapHeader) + Hdr.ImageOffset - cdrfBitmapHeaderImageOffsetCorrect; } // grab the image data, it's in the same sort of format as a DIB file. Helpfully // if(!RIFF->GetChunkData((ADDR)Image, ScanlineLength * Hdr.SizeY, SourceOffset)) // { // FreeDIB(ImageHeader, Image); // return 0; // } INT32 SizeLeftToGet = ScanlineLength * Hdr.SizeY; INT32 Size, Got = 0; while(SizeLeftToGet > 0) { if(SizeLeftToGet > PROGRESS_BLOCKSIZE) Size = PROGRESS_BLOCKSIZE; else Size = SizeLeftToGet; if(!RIFF->GetChunkData((ADDR)Image + Got, Size, SourceOffset + Got)) { FreeDIB(ImageHeader, Image); return 0; } SizeLeftToGet -= Size; Got += Size; C->UpdateProgress(TRUE); } // OK, it's all filled in. Create a KernelBitmap from it. // first of all, get ourself a nice OIL bitmap WinBitmap *WinB = new WinBitmap(ImageHeader, Image); if(WinB == 0) { FreeDIB(ImageHeader, Image); return 0; } // get it to cache some interesting stuff WinB->CacheGeometry(); // and now get a KernelBitmap KernelBitmap *KerB = new KernelBitmap(WinB); if(KerB == 0) { delete WinB; return 0; } // and that's it for now, folks return KerB; }
KernelBitmap *CDRBitmap::ConvertPattern(RIFFFile *RIFF, DWORD *Reference, CDRFilter *C) { TRACEUSER( "Ben", _T("Converting pattern\n")); // check various things ERROR3IF(RIFF->GetObjChunkType() != cdrT_bmpf, "ConvertPattern called for non-pattern RIFF chunk"); ERROR3IF(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK, "ConvertPattern called for a non-chunk RIFF object"); if(RIFF->GetObjSize() < sizeof(cdrfPatternBitmapHeader)) { // Empty 'if' statement // Anyone's guess if this was intended // Changed to this form to remove a compiler warning // Markn 19/3/99 } // get some data from the RIFF file cdrfPatternBitmapHeader Hdr; // get the header from offset 0 if(!RIFF->GetChunkData((ADDR)&Hdr, sizeof(Hdr), 0)) return 0; // check the header... if(((Hdr.SizeX * Hdr.SizeY) / 8) > Hdr.DataSize || Hdr.DataSize > (DWORD)RIFF->GetObjSize()) { TRACEUSER( "Ben", _T("Header in CDR pattern doesn't check out\n")); return 0; } // store the reference TRACEUSER( "Ben", _T("Pattern reference = %X\n"), Hdr.Reference); *Reference = Hdr.Reference; // OK, create a bitmap... // it's always a 1 bpp bitmap LPBYTE Image; LPBITMAPINFO ImageHeader; ImageHeader = AllocDIB(Hdr.SizeX, Hdr.SizeX, 1, &Image); if(ImageHeader == 0) return 0; // check and then fill in the image data if(ImageHeader->bmiHeader.biSizeImage < (Hdr.DataSize - (sizeof(DWORD) * 3))) { FreeDIB(ImageHeader, Image); return 0; } // set some palette data ImageHeader->bmiColors[0].rgbBlue = 0; ImageHeader->bmiColors[0].rgbGreen = 0; ImageHeader->bmiColors[0].rgbRed = 0; ImageHeader->bmiColors[0].rgbReserved = 0; ImageHeader->bmiColors[1].rgbBlue = 0xff; ImageHeader->bmiColors[1].rgbGreen = 0xff; ImageHeader->bmiColors[1].rgbRed = 0xff; ImageHeader->bmiColors[1].rgbReserved = 0; // corel bitmaps align the scanlines to the nearest byte, not the nearest word // how long is a corel scanline INT32 SourceScanlineLength = (Hdr.SizeX + 7) / 8; // how long is the destination scanline? INT32 DestScanlineLength = ((Hdr.SizeX + 31) / 32) * 4; // sanity check ERROR3IF(DestScanlineLength < SourceScanlineLength, "Problem with scanline length calculations"); // set up offsets of current line INT32 SourceOffset = Hdr.DataOffset + (sizeof(DWORD) * 3); INT32 DestOffset = ImageHeader->bmiHeader.biSizeImage - DestScanlineLength; // grab the image data, backwards INT32 Line; for(Line = 0; Line < (INT32)Hdr.SizeY; Line++) { if(!RIFF->GetChunkData(((ADDR)Image) + DestOffset, SourceScanlineLength, SourceOffset)) { FreeDIB(ImageHeader, Image); return 0; } SourceOffset += SourceScanlineLength; DestOffset -= DestScanlineLength; if((Line & 0xf) == 0) C->UpdateProgress(TRUE); } // OK, it's all filled in. Create a KernelBitmap from it. // first of all, get ourself a nice OIL bitmap WinBitmap *WinB = new WinBitmap(ImageHeader, Image); if(WinB == 0) { FreeDIB(ImageHeader, Image); return 0; } // and now get a KernelBitmap KernelBitmap *KerB = new KernelBitmap(WinB); if(KerB == 0) { delete WinB; return 0; } // and that's it for now, folks return KerB; }
LPBITMAPINFO GRenderWinG::GetLPBits( INT32 Width, INT32 Height, INT32 Depth, LPBYTE*lplpBits) { // get a bitmap header with no bits const LPBITMAPINFO bmInfo = AllocDIB( Width, Height, Depth, NULL ); if (!bmInfo) return NULL; // tell it the sort of palette we want - we want Gavin's if (Depth==8) { #if 0 RGBQUAD *rgb = bmInfo->bmiColors; LPPALETTEENTRY lpPal = GetRecommendedPalette()->palPalEntry; size_t i ; for ( i=0 ; i<256 ; i++ ) { rgb->rgbRed = lpPal->peRed; rgb->rgbGreen = lpPal->peGreen; rgb->rgbBlue = lpPal->peBlue; rgb->rgbReserved = 0; rgb ++; lpPal++; } #else GetSystemPaletteEntries ( RenderDC->m_hDC, 0, 256, (LPPALETTEENTRY) bmInfo->bmiColors ) ; RGBQUAD *rgb = bmInfo->bmiColors ; // Swap R and B. size_t i ; for ( i=0 ; i<256 ; i++ ) { BYTE t = rgb->rgbRed ; rgb->rgbRed = rgb->rgbBlue ; rgb->rgbBlue = t ; rgb ++ ; } #endif } // if WinG wants it upside-down then go for it if (RecommendedDIB.biHeight == -1) { Inverted = TRUE; bmInfo->bmiHeader.biHeight = -bmInfo->bmiHeader.biHeight; } else Inverted = FALSE; // now get a lovely WinG bitmap WinGBitmap = pWinGCreateBitmap( OffScreenDC, bmInfo, (void FAR* FAR *)lplpBits ); if (WinGBitmap==NULL) { TRACE( _T("WinGCreateBitmap failed\n")); FreeDIB( bmInfo, NULL ); return NULL; } // turn it back the other way else Gavin is likely to get confused if (Inverted) bmInfo->bmiHeader.biHeight = -bmInfo->bmiHeader.biHeight; //TRACE( _T("WinG Alloc %lx=%lx:%lx\n"), this, bmInfo, *lplpBits); return bmInfo; }
BOOL OutputPNG::StartFile( LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette, UINT32 OutputDepth, DWORD CompressionType, UINT32 FinalHeight, INT32 ExportSize, UINT32 DitherType ) { TRACEUSER( "Jonathan", _T("PNG write: Start\n")); ERROR2IF( lpHeader==NULL , FALSE, "OutputPNG::StartFile NULL lpHeader"); // Set up memory pointers to NULL if (DestBitmapInfo && DestBitmapBytes) { FreeDIB( DestBitmapInfo, DestBitmapBytes ); DestBitmapInfo = NULL; DestBitmapBytes = NULL; } // DestBitmapInfo = NULL; // DestBitmapBytes = NULL; if (OutputPalette) { CCFree(OutputPalette); OutputPalette = NULL; } // OutputPalette = NULL; IsFirstStrip = TRUE; HeightWritten = 0; // remember input args BitmapInfo = *lpHeader; // take a copy of user's header CurrentExportSize = ExportSize; // size set up for the progress bar HeightWanted = FinalHeight; // the actual height of the export required Dither = DitherType; // We will need to have the entire image present before writing out so that we can // cope with interlacing and transparency, so create that DIB // Set up the information header for the dib which we hold during export UINT32 LineWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, OutputDepth ); INT32 PalSize = 0; BOOL ok = SetUpInfoHeader(lpHeader, OutputDepth, CompressionType, LineWidth, FinalHeight, &PalSize); // Claim memory for the bitmap if (ok) { DestBitmapInfo = AllocDIB( BitmapInfo.biWidth, FinalHeight, OutputDepth, &DestBitmapBytes ); ok = (DestBitmapInfo != NULL) && (DestBitmapBytes != NULL); } // Transfer across the required other bits of info if (ok) { DestBitmapInfo->bmiHeader.biXPelsPerMeter = BitmapInfo.biXPelsPerMeter; DestBitmapInfo->bmiHeader.biYPelsPerMeter = BitmapInfo.biYPelsPerMeter; DestBitmapInfo->bmiHeader.biClrUsed = PalSize; } // Point the place to put the next strip of data at the start ready for the first strip pNextStrip = DestBitmapBytes; // Take a copy of the palette if (ok && PalSize && Palette) { const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PalSize ); OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal ); if (OutputPalette != NULL) memcpy( OutputPalette, Palette, TotalPal ); else ok = FALSE; } // Clean up if an error happened if (!ok) { // Free up the DIB that we have just created FreeDIB( DestBitmapInfo, DestBitmapBytes ); DestBitmapInfo = NULL; DestBitmapBytes = NULL; if (OutputPalette != NULL) { CCFree(OutputPalette); OutputPalette = NULL; } } return ok; }
HRESULT CImgBitsDIB::AllocCopyBitmap(HBITMAP hbm, BOOL fPalColors, LONG lTrans) { HRESULT hr; LONG iBitCount; struct { BITMAPINFOHEADER bmih; union { RGBQUAD rgb[256]; WORD windex[256]; DWORD dwbc[3]; }; } header; HDC hdc; hdc = GetMemoryDC(); if(!hdc) { return E_OUTOFMEMORY; } memset(&header, 0, sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256); header.bmih.biSize = sizeof(BITMAPINFOHEADER); GetDIBits(hdc, hbm, 0, 0, NULL, (BITMAPINFO*)&header, fPalColors?DIB_PAL_COLORS:DIB_RGB_COLORS); // A second call to GetDIBits should get the color table if any, but it doesn't work on Win95, so we use // GetDIBColorTable instead (dbau) if(header.bmih.biBitCount <= 8) { HBITMAP hbmSav; hbmSav = (HBITMAP)SelectObject(hdc, hbm); GetDIBColorTable(hdc, 0, 1<<header.bmih.biBitCount, header.rgb); SelectObject(hdc, hbmSav); } iBitCount = header.bmih.biBitCount; if(iBitCount == 16) { if(header.bmih.biCompression!=BI_BITFIELDS || header.dwbc[0]!=MASK565_0 || header.dwbc[1]!=MASK565_1 || header.dwbc[2]!=MASK565_2) { iBitCount = 15; } } BOOL fColorTable = (!fPalColors && iBitCount<=8); if(fColorTable) { hr = AllocDIB(iBitCount, header.bmih.biWidth, header.bmih.biHeight, header.rgb, 1<<iBitCount, lTrans, lTrans==-1); } else { hr = AllocDIB(iBitCount, header.bmih.biWidth, header.bmih.biHeight, NULL, 0, -1, TRUE); } GetDIBits(hdc, hbm, 0, header.bmih.biHeight, GetBits(), (BITMAPINFO*)&header, fPalColors?DIB_PAL_COLORS:DIB_RGB_COLORS); ReleaseMemoryDC(hdc); return S_OK; }