void save_stream_to_alpha_image(Stream* str, GfxImageColorMap* colorMap, int width, int height, Stream* maskStr, GfxImageColorMap* maskColorMap, int maskWidth, int maskHeight, char* file_name) { if (fif != FIF_PNG || width == 0 || height == 0 || maskWidth == 0 || maskHeight == 0) { save_stream_to_image(str, colorMap, width, height, colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1, file_name, gFalse); return; } // allocate buffer int row_size = width * 4; unsigned char* buf = (unsigned char*)malloc(height * row_size); if (!buf) return; // read mask data ImageStream* mask_str = new ImageStream(maskStr, maskWidth, maskColorMap->getNumPixelComps(), maskColorMap->getBits()); mask_str->reset(); Guchar* mask_line = mask_str->getLine(); int old_mask_row = 0; for (int y = 0; y < height; ++y) { unsigned char* pbuf = buf + row_size * y; int new_mask_row = y * maskHeight / height; for (int i = old_mask_row; i < new_mask_row; ++i) { mask_line = mask_str->getLine(); } old_mask_row = new_mask_row; int old_mask_column = 0; for (int x = 0; x < width; ++x) { int new_mask_column = x * maskWidth / width; mask_line += maskColorMap->getNumPixelComps() * (new_mask_column - old_mask_column); old_mask_column = new_mask_column; GfxGray gray; maskColorMap->getGray(mask_line, &gray); pbuf[3] = colToByte(gray); pbuf += 4; } } delete mask_str; // read image data ImageStream* img_str = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits()); img_str->reset(); for (int y = 0; y < height; ++y) { unsigned char* pbuf = buf + row_size * y; Guchar* line = img_str->getLine(); for (int x = 0; x < width; ++x) { GfxRGB rgb; colorMap->getRGB(line, &rgb); // int alpha = pbuf[3]; // if (alpha < 255 && alpha > 0) // { // pbuf[0] = (colToByte(rgb.b) + alpha - 255) * 255 / alpha; // pbuf[1] = (colToByte(rgb.g) + alpha - 255) * 255 / alpha; // pbuf[2] = (colToByte(rgb.r) + alpha - 255) * 255 / alpha; // } // else { pbuf[0] = colToByte(rgb.b); pbuf[1] = colToByte(rgb.g); pbuf[2] = colToByte(rgb.r); } line += colorMap->getNumPixelComps(); pbuf += 4; } } delete img_str; // create image FIBITMAP* fib = FreeImage_ConvertFromRawBits(buf, width, height, row_size, 32, 0, 0, 0, 1); free(buf); // save FreeImage_SetDotsPerMeterX(fib, 72 * 10000 / 254); FreeImage_SetDotsPerMeterY(fib, 72 * 10000 / 254); int flag = 0; if (fif == FIF_JPEG) flag = jpg_quality; else if (fif == FIF_TIFF && tiff_jpeg) flag = TIFF_JPEG; if (!FreeImage_Save(fif, fib, file_name, flag)) error(-1, "Couldn't create file '%s'", file_name); FreeImage_Unload(fib); }
void save_stream_to_image(Stream* str, GfxImageColorMap* color_map, int width, int height, GBool mono, char* file_name, GBool mask) { // read raw data from memory FIBITMAP* fib; if (mono) { int size = height * ((width + 7) / 8); unsigned char* buf = (unsigned char*)malloc(size); if (!buf) return; unsigned char* p = buf; str->reset(); for (int i = 0; i < size; i++) *p++ = str->getChar(); str->close(); fib = FreeImage_ConvertFromRawBits(buf, width, height, (width + 7) / 8, 1, 0, 0, 0, 1); RGBQUAD* pal = FreeImage_GetPalette(fib); pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = (mask ? 0 : 255); pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = (mask ? 255 : 0); free(buf); } else { int row_size = width * 3; if (row_size % 4) row_size += (4 - row_size % 4); unsigned char* buf = (unsigned char*)malloc(height * row_size); if (!buf) return; ImageStream* img_str = new ImageStream(str, width, color_map->getNumPixelComps(), color_map->getBits()); img_str->reset(); Guchar* p; unsigned char* pbuf; GfxRGB rgb; for (int y = 0; y < height; ++y) { p = img_str->getLine(); pbuf = buf + row_size * y; for (int x = 0; x < width; ++x) { color_map->getRGB(p, &rgb); pbuf[0] = colToByte(rgb.b); pbuf[1] = colToByte(rgb.g); pbuf[2] = colToByte(rgb.r); p += color_map->getNumPixelComps(); pbuf += 3; } } fib = FreeImage_ConvertFromRawBits(buf, width, height, row_size, 24, 0, 0, 0, 1); delete img_str; free(buf); } // adjust color depth if (fif == FIF_GIF && !mono) { FIBITMAP* fib_temp = fib; fib = FreeImage_ColorQuantize(fib_temp, FIQ_WUQUANT); FreeImage_Unload(fib_temp); } else if (fif == FIF_JPEG && mono) { FIBITMAP* fib_temp = fib; fib = FreeImage_ConvertTo8Bits(fib_temp); FreeImage_Unload(fib_temp); } // save FreeImage_SetDotsPerMeterX(fib, 72 * 10000 / 254); FreeImage_SetDotsPerMeterY(fib, 72 * 10000 / 254); int flag = 0; if (fif == FIF_JPEG) flag = jpg_quality; else if (fif == FIF_TIFF && tiff_jpeg && !mono) flag = TIFF_JPEG; if (!FreeImage_Save(fif, fib, file_name, flag)) error(-1, "Couldn't create file '%s'", file_name); FreeImage_Unload(fib); }
void ImagesMemoryOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,int width, int height,GfxImageColorMap *colorMap,int *maskColors, GBool inlineImg) { ImageStream *imgStr; Guchar *p; GfxRGB rgb; int x, y; int c; int size, i; ImageInfo *img =new ImageInfo(); int initBufSize=16384; int bufSize=initBufSize; byte *buff=0; img->bytes =(byte *)malloc(bufSize); if(!img->bytes) throw "Memory allocation failure!"; img->height=height; img->width =width; img->name=0; //if(ref && ref->getName()){ //img->name=new char[1024]; //sprintf(img->name,"%s",ref->getName()); //} img->ismask=true; img->index=imgNum; img->type=0; int count=0; // dump JPEG file if (dumpJPEG && str->getKind() == strDCT && (colorMap->getNumPixelComps() == 1 || colorMap->getNumPixelComps() == 3) && !inlineImg) { // initialize stream str = ((DCTStream *)str)->getRawStream(); str->reset(); // copy the stream while ((c = str->getChar()) != EOF) { //Resize buffer preserving items if(count+1>bufSize){ bufSize+=initBufSize; img->bytes=(byte *)realloc(img->bytes,bufSize+1); if(!img->bytes) throw "Memory allocation failure!"; } img->bytes[count]=c; count++; } img->size=count; str->close(); // dump PBM file (P4) } else if (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1) { img->type=1; // initialize stream str->reset(); // copy the stream fprintf(stderr,"Copy Stream PBM"); size = height * ((width + 7) / 8); for (i = 0; i < size; ++i) { c =str->getChar() ^ 0xff; //Resize buffer preserving items if(count+1>bufSize){ bufSize+=initBufSize; img->bytes=(byte *)realloc(img->bytes,bufSize+1); if(!img->bytes) throw "Memory allocation failure!"; } img->bytes[count]=c; count++; } img->size=count; str->close(); // dump PPM file (P6) } else { img->type=2; // initialize stream imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),colorMap->getBits()); imgStr->reset(); img->numcomps = colorMap->getNumPixelComps(); // for each line... for (y = 0; y < height; ++y) { // write the line p = imgStr->getLine(); for (x = 0; x < width; ++x) { colorMap->getRGB(p, &rgb); //Resize buffer preserving items if((count+colorMap->getNumPixelComps()+1)>bufSize){ bufSize+=initBufSize; img->bytes=(byte *)realloc(img->bytes,bufSize+1); if(!img->bytes) throw "Memory allocation failure!"; } //byte rgbc = RGB(colToByte(rgb.r),colToByte(rgb.g),colToByte(rgb.b)); //img->bytes[count]= rgbc; //we need a bitmap of 24 bits if(img->numcomps==1) //mono { //GfxColor colr; //colorMap->getColor(p,&colr); img->bytes[count]= RGB(colToByte(rgb.r),colToByte(rgb.g),colToByte(rgb.b)); } else if(img->numcomps == 4) //ARGB 32bits { img->bytes[count+3]=255; img->bytes[count+2]= (byte)colToByte(rgb.r); img->bytes[count+1]= (byte)colToByte(rgb.g); img->bytes[count] = (byte)colToByte(rgb.b); } else if(img->numcomps == 3) //RGB 24bits { img->bytes[count+2]=(byte)colToByte(rgb.r); img->bytes[count+1]=(byte)colToByte(rgb.g); img->bytes[count] =(byte)colToByte(rgb.b); } p += colorMap->getNumPixelComps(); count+=colorMap->getNumPixelComps(); } } img->size=count; delete imgStr; } _Images.Add(*img); }