/** * exports the image into a RGBA buffer, Useful for OpenGL applications. * \param buffer: output memory buffer pointer. Must be NULL, * the function allocates and fill the memory, * the application must free the buffer, see also FreeMemory(). * \param size: output memory buffer size. * \param bFlipY: direction of Y axis. default = false. * \return true if everything is ok */ bool CxImage::Encode2RGBA(uint8_t * &buffer, int32_t &size, bool bFlipY) { if (buffer!=NULL){ strcpy(info.szLastError,"the buffer must be empty"); return false; } CxMemFile file; file.Open(); if(Encode2RGBA(&file,bFlipY)){ buffer=file.GetBuffer(); size=file.Size(); return true; } return false; }
/** * Saves to memory buffer the image in a specific format. * \param buffer: output memory buffer pointer. Must be NULL, * the function allocates and fill the memory, * the application must free the buffer, see also FreeMemory(). * \param size: output memory buffer size. * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS * \return true if everything is ok */ bool CxImage::Encode(BYTE * &buffer, long &size, DWORD imagetype) { if (buffer!=NULL){ strcpy(info.szLastError,"the buffer must be empty"); return false; } CxMemFile file; file.Open(); if(Encode(&file,imagetype)){ buffer=file.GetBuffer(); size=file.Size(); return true; } return false; }
bool CxImagePCX::Encode(CxFile * hFile) { if (EncodeSafeCheck(hFile)) return false; try { PCXHEADER pcxHeader; memset(&pcxHeader,0,sizeof(pcxHeader)); pcxHeader.Manufacturer = PCX_MAGIC; pcxHeader.Version = 5; pcxHeader.Encoding = 1; pcxHeader.Xmin = 0; pcxHeader.Ymin = 0; pcxHeader.Xmax = (WORD)head.biWidth-1; pcxHeader.Ymax = (WORD)head.biHeight-1; pcxHeader.Hres = (WORD)info.xDPI; pcxHeader.Vres = (WORD)info.yDPI; pcxHeader.Reserved = 0; pcxHeader.PaletteType = head.biClrUsed==0; switch(head.biBitCount){ case 24: case 8: { pcxHeader.BitsPerPixel = 8; pcxHeader.ColorPlanes = head.biClrUsed==0 ? 3 : 1; #if CXIMAGE_SUPPORT_ALPHA if (AlphaIsValid() && head.biClrUsed==0) pcxHeader.ColorPlanes =4; #endif //CXIMAGE_SUPPORT_ALPHA pcxHeader.BytesPerLine = (WORD)head.biWidth; break; } default: //(4 1) pcxHeader.BitsPerPixel = 1; pcxHeader.ColorPlanes = head.biClrUsed==16 ? 4 : 1; pcxHeader.BytesPerLine = (WORD)((head.biWidth * pcxHeader.BitsPerPixel + 7)>>3); } if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){ pcxHeader.ColorMap[0][0] = pcxHeader.ColorMap[0][1] = pcxHeader.ColorMap[0][2] = 0; pcxHeader.ColorMap[1][0] = pcxHeader.ColorMap[1][1] = pcxHeader.ColorMap[1][2] = 255; } if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 4){ RGBQUAD c; for (int i = 0; i < 16; i++){ c=GetPaletteColor(i); pcxHeader.ColorMap[i][0] = c.rgbRed; pcxHeader.ColorMap[i][1] = c.rgbGreen; pcxHeader.ColorMap[i][2] = c.rgbBlue; } } pcxHeader.BytesPerLine = (pcxHeader.BytesPerLine + 1)&(~1); if (hFile->Write(&pcxHeader, sizeof(pcxHeader), 1) == 0 ) throw "cannot write PCX header"; CxMemFile buffer; buffer.Open(); BYTE c,n; long x,y; if (head.biClrUsed==0){ for (y = head.biHeight-1; y >=0 ; y--){ for (int p=0; p<pcxHeader.ColorPlanes; p++){ c=n=0; for (x = 0; x<head.biWidth; x++){ if (p==0) PCX_PackPixels(GetPixelColor(x,y).rgbRed,c,n,buffer); else if (p==1) PCX_PackPixels(GetPixelColor(x,y).rgbGreen,c,n,buffer); else if (p==2) PCX_PackPixels(GetPixelColor(x,y).rgbBlue,c,n,buffer); #if CXIMAGE_SUPPORT_ALPHA else if (p==3) PCX_PackPixels(AlphaGet(x,y),c,n,buffer); #endif //CXIMAGE_SUPPORT_ALPHA } PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer); } } hFile->Write(buffer.GetBuffer(false),buffer.Size(),1); } else if (head.biBitCount==8) { for (y = head.biHeight-1; y >=0 ; y--){ c=n=0; for (x = 0; x<head.biWidth; x++){ PCX_PackPixels(GetPixelIndex(x,y),c,n,buffer); } PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer); } hFile->Write(buffer.GetBuffer(false),buffer.Size(),1); if (head.biBitCount == 8){ hFile->PutC(0x0C); BYTE* pal = (BYTE*)malloc(768); RGBQUAD c; for (int i=0;i<256;i++){ c=GetPaletteColor(i); pal[3*i+0] = c.rgbRed; pal[3*i+1] = c.rgbGreen; pal[3*i+2] = c.rgbBlue; } hFile->Write(pal,768,1); free(pal); } } else { //(head.biBitCount==4) || (head.biBitCount==1) RGBQUAD *rgb = GetPalette(); bool binvert = false; if (CompareColors(&rgb[0],&rgb[1])>0) binvert=(head.biBitCount==1); BYTE* plane = (BYTE*)malloc(pcxHeader.BytesPerLine); BYTE* raw = (BYTE*)malloc(head.biWidth); for(y = head.biHeight-1; y >=0 ; y--) { for( x = 0; x < head.biWidth; x++) raw[x] = (BYTE)GetPixelIndex(x,y); if (binvert) for( x = 0; x < head.biWidth; x++) raw[x] = 1-raw[x]; for( x = 0; x < pcxHeader.ColorPlanes; x++ ) { PCX_PixelsToPlanes(raw, head.biWidth, plane, x); PCX_PackPlanes(plane, pcxHeader.BytesPerLine, buffer); } } free(plane); free(raw); hFile->Write(buffer.GetBuffer(false),buffer.Size(),1); } } catch (char *message) { strncpy(info.szLastError,message,255); return false; } return true; }