bool CoImageTIF::Encode(FILE* pFile, bool bAppend)
{
	if (EncodeSafeCheck(pFile))
		return false;

	XFileDisk hFile(pFile);

	try
	{
		if (&hFile==NULL) throw CVLIB_IMG_ERR_NOFILE;
// 		if (GetPalette() == NULL) throw CVLIB_IMG_ERR_NOIMAGE;
		
		// <RJ> replaced "w+b" with "a", to append an image directly on an existing file
		if (m_tif2==NULL) m_tif2 =(void*)_TIFFOpenEx(&hFile, "a");
		if (m_tif2==NULL) throw "initialization fail";
		
		if (bAppend || m_pages) m_multipage=true;
		m_pages++;
		
		if (!EncodeBody(m_tif2,m_multipage,m_pages,m_pages)) throw "Error saving TIFF file";
		if (bAppend) 
		{
			if (!TIFFWriteDirectory((TIFF*)m_tif2)) throw "Error saving TIFF directory";
		}
	} 
	catch (char *message) 
	{
		strncpy(m_Info.szLastError,message,255);
		if (m_tif2)
		{
			TIFFClose((TIFF*)m_tif2);
			m_tif2=NULL;
			m_multipage=false;
			m_pages=0;
		}
		return false;
	}
	if (!bAppend)
	{
		TIFFClose((TIFF*)m_tif2);
		m_tif2=NULL;
		m_multipage=false;
		m_pages=0;
	}
	return true;
}
Exemple #2
0
bool CxImageSKA::Encode(CxFile * hFile)
{
	if (EncodeSafeCheck(hFile)) return false;

	if(head.biBitCount > 8)	{
		strcpy(info.szLastError,"SKA Images must be 8 bit or less");
		return false;
	}

	SKAHEADER ska_header;

	ska_header.Width = (unsigned short)GetWidth();
	ska_header.Height = (unsigned short)GetHeight();
	ska_header.BppExp = 3;
	ska_header.dwUnknown = 0x01000000;

    ska_header.Width = ntohs(ska_header.Width);
    ska_header.Height = ntohs(ska_header.Height);
    ska_header.dwUnknown = ntohl(ska_header.dwUnknown);

	hFile->Write(&ska_header,sizeof(SKAHEADER),1);

    ska_header.Width = ntohs(ska_header.Width);
    ska_header.Height = ntohs(ska_header.Height);
    ska_header.dwUnknown = ntohl(ska_header.dwUnknown);

	if (head.biBitCount<8) IncreaseBpp(8);

	rgb_color pal[256];
	for(int idx=0; idx<256; idx++){
		GetPaletteColor(idx,&(pal[idx].r),&(pal[idx].g),&(pal[idx].b));
	}

	hFile->Write(pal,256*sizeof(rgb_color),1);

	BYTE* src = GetBits(ska_header.Height-1);
	for(int y=0;y<ska_header.Height;y++){
		hFile->Write(src,ska_header.Width,1);
		src -= GetEffWidth();
	}

	return true;
}
bool CxImageBMP::Encode(CxFile * hFile)
{

	if (EncodeSafeCheck(hFile)) return false;

	BITMAPFILEHEADER	hdr;

	hdr.bfType = 0x4d42;   // 'BM' WINDOWS_BITMAP_SIGNATURE
	hdr.bfSize = GetSize() + 14 /*sizeof(BITMAPFILEHEADER)*/;
	hdr.bfReserved1 = hdr.bfReserved2 = 0;
	hdr.bfOffBits = 14 /*sizeof(BITMAPFILEHEADER)*/ + head.biSize + GetPaletteSize();

	 //copy attributes
	memcpy(pDib,&head,sizeof(BITMAPINFOHEADER));
    // Write the file header
	hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
    // Write the DIB header and the pixels
	hFile->Write(pDib,GetSize(),1);
	return true;
}
Exemple #4
0
bool CxImageJPG::Encode(CxFile * hFile)
{
	if (EncodeSafeCheck(hFile)) return false;

	if (head.biClrUsed!=0 && !IsGrayScale()){
		strcpy(info.szLastError,"JPEG can save only RGB or GreyScale images");
		return false;
	}	

	/* This struct contains the JPEG compression parameters and pointers to
	* working space (which is allocated as needed by the JPEG library).
	* It is possible to have several such structures, representing multiple
	* compression/decompression processes, in existence at once.  We refer
	* to any one struct (and its associated working data) as a "JPEG object".
	*/
	struct jpeg_compress_struct cinfo;
	/* This struct represents a JPEG error handler.  It is declared separately
	* because applications often want to supply a specialized error handler
	* (see the second half of this file for an example).  But here we just
	* take the easy way out and use the standard error handler, which will
	* print a message on stderr and call exit() if compression fails.
	* Note that this struct must live as long as the main JPEG parameter
	* struct, to avoid dangling-pointer problems.
	*/
	//struct jpeg_error_mgr jerr;
	/* We use our private extension JPEG error handler. <CSC> */
	struct ima_error_mgr jerr;
	jerr.buffer=info.szLastError;
	/* More stuff */
	int row_stride;		/* physical row width in image buffer */
	JSAMPARRAY buffer;		/* Output row buffer */

	/* Step 1: allocate and initialize JPEG compression object */
	/* We have to set up the error handler first, in case the initialization
	* step fails.  (Unlikely, but it could happen if you are out of memory.)
	* This routine fills in the contents of struct jerr, and returns jerr's
	* address which we place into the link field in cinfo.
	*/
	//cinfo.err = jpeg_std_error(&jerr); <CSC>
	/* We set up the normal JPEG error routines, then override error_exit. */
	cinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = ima_jpeg_error_exit;

	/* Establish the setjmp return context for my_error_exit to use. */
	if (setjmp(jerr.setjmp_buffer)) {
		/* If we get here, the JPEG code has signaled an error.
		* We need to clean up the JPEG object, close the input file, and return.
		*/
		strcpy(info.szLastError, jerr.buffer); //<CSC>
		jpeg_destroy_compress(&cinfo);
		return 0;
	}
	
	/* Now we can initialize the JPEG compression object. */
	jpeg_create_compress(&cinfo);
	/* Step 2: specify data destination (eg, a file) */
	/* Note: steps 2 and 3 can be done in either order. */
	/* Here we use the library-supplied code to send compressed data to a
	* stdio stream.  You can also write your own code to do something else.
	* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
	* requires it in order to write binary files.
	*/

	//jpeg_stdio_dest(&cinfo, outfile);
	CxFileJpg dest(hFile);
    cinfo.dest = &dest;

	/* Step 3: set parameters for compression */
	/* First we supply a description of the input image.
	* Four fields of the cinfo struct must be filled in:
	*/
	cinfo.image_width = GetWidth(); 	// image width and height, in pixels
	cinfo.image_height = GetHeight();

	if (IsGrayScale()){
		cinfo.input_components = 1;			// # of color components per pixel
		cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
	} else {
		cinfo.input_components = 3; 	// # of color components per pixel
		cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
	}

	/* Now use the library's routine to set default compression parameters.
	* (You must set at least cinfo.in_color_space before calling this,
	* since the defaults depend on the source color space.)
	*/
	jpeg_set_defaults(&cinfo);
	/* Now you can set any non-default parameters you wish to.
	* Here we just illustrate the use of quality (quantization table) scaling:
	*/
	//jpeg_set_quality(&cinfo, info.nQuality, TRUE /* limit to baseline-JPEG values */);
#ifdef C_ARITH_CODING_SUPPORTED
	if ((GetCodecOption() & ENCODE_ARITHMETIC) != 0)
		cinfo.arith_code = TRUE;
#endif
#ifdef ENTRPY_OPT_SUPPORTED
	if ((GetCodecOption() & ENCODE_OPTIMIZE) != 0)
		cinfo.optimize_coding = TRUE;
#endif
	if ((GetCodecOption() & ENCODE_GRAYSCALE) != 0)
		jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
	if ((GetCodecOption() & ENCODE_SMOOTHING) != 0)
		cinfo.smoothing_factor = m_nSmoothing;
	jpeg_set_quality(&cinfo, GetJpegQuality(), (GetCodecOption() & ENCODE_BASELINE) != 0);
#ifdef C_PROGRESSIVE_SUPPORTED
	if ((GetCodecOption() & ENCODE_PROGRESSIVE) != 0)
		jpeg_simple_progression(&cinfo);
#endif
#ifdef C_LOSSLES_SUPPORTED
	if ((GetCodecOption() & ENCODE_LOSSLESS) != 0)
		jpeg_simple_lossless(&cinfo, m_nPredictor, m_nPointTransform);
#endif

	cinfo.density_unit=1;
	cinfo.X_density=(unsigned short)GetXDPI();
	cinfo.Y_density=(unsigned short)GetYDPI();

	/* Step 4: Start compressor */
	/* TRUE ensures that we will write a complete interchange-JPEG file.
	* Pass TRUE unless you are very sure of what you're doing.
	*/
	jpeg_start_compress(&cinfo, TRUE);

	/* Step 5: while (scan lines remain to be written) */
	/*           jpeg_write_scanlines(...); */
	/* Here we use the library's state variable cinfo.next_scanline as the
	* loop counter, so that we don't have to keep track ourselves.
	* To keep things simple, we pass one scanline per call; you can pass
	* more if you wish, though.
	*/
	row_stride = info.dwEffWidth;	/* JSAMPLEs per row in image_buffer */

	//<DP> "8+row_stride" fix heap deallocation problem during debug???
	buffer = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, 8+row_stride, 1);

	CImageIterator iter(this);

	iter.Upset();
	while (cinfo.next_scanline < cinfo.image_height) {
		// info.nProgress = (long)(100*cinfo.next_scanline/cinfo.image_height);
		iter.GetRow(buffer[0], row_stride);
		// not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
		if (head.biClrUsed==0){				 // swap R & B for RGB images
			RGBtoBGR(buffer[0], row_stride); // Lance : 1998/09/01 : Bug ID: EXP-2.1.1-9
		}
		iter.PrevRow();
		(void) jpeg_write_scanlines(&cinfo, buffer, 1);
	}

	/* Step 6: Finish compression */
	jpeg_finish_compress(&cinfo);

	/* Step 7: release JPEG compression object */
	/* This is an important step since it will release a good deal of memory. */
	jpeg_destroy_compress(&cinfo);

	/* And we're done! */
	return true;
}
Exemple #5
0
bool CxImageJ2K::Encode(CxFile * hFile)
{
	if (EncodeSafeCheck(hFile)) return false;

	if (head.biClrUsed!=0 && !IsGrayScale()){
		strcpy(info.szLastError,"J2K can save only RGB or GrayScale images");
		return false;
	}

    int i,x,y;
    j2k_image_t *img;
    j2k_cp_t *cp;
    j2k_tcp_t *tcp;
    j2k_tccp_t *tccp;

	img = (j2k_image_t *)calloc(sizeof(j2k_image_t),1);
	cp = (j2k_cp_t *)calloc(sizeof(j2k_cp_t),1);

    cp->tx0=0; cp->ty0=0;
    cp->tw=1; cp->th=1;
    cp->tcps=(j2k_tcp_t*)calloc(sizeof(j2k_tcp_t),1);
    tcp=&cp->tcps[0];

	long w=head.biWidth;
	long h=head.biHeight;
 
	tcp->numlayers=1;
	for (i=0;i<tcp->numlayers;i++) tcp->rates[i]=(w*h*GetJpegQuality())/600;


    if (IsGrayScale()) {
        img->x0=0;
		img->y0=0;
		img->x1=w;
		img->y1=h;
        img->numcomps=1;
        img->comps=(j2k_comp_t*)calloc(sizeof(j2k_comp_t),1);
        img->comps[0].data=(int*)calloc(w*h*sizeof(int),1);
        img->comps[0].prec=8;
        img->comps[0].sgnd=0;
        img->comps[0].dx=1;
        img->comps[0].dy=1;
		for (i=0,y=0; y<h; y++) {
			for (x=0; x<w; x++,i++){
				img->comps[0].data[i]=GetPixelIndex(x,h-1-y);
			}
		}
    } else if (!IsIndexed()) {
        img->x0=0;
		img->y0=0;
		img->x1=w;
		img->y1=h;
        img->numcomps=3;
        img->comps=(j2k_comp_t*)calloc(img->numcomps*sizeof(j2k_comp_t),1);
        for (i=0; i<img->numcomps; i++) {
            img->comps[i].data=(int*)calloc(w*h*sizeof(int),1);
            img->comps[i].prec=8;
            img->comps[i].sgnd=0;
            img->comps[i].dx=1;
            img->comps[i].dy=1;
        }
		RGBQUAD c;
        for (i=0,y=0; y<h; y++) {
			for (x=0; x<w; x++,i++){
				c=GetPixelColor(x,h-1-y);
				img->comps[0].data[i]=c.rgbRed;
				img->comps[1].data[i]=c.rgbGreen;
				img->comps[2].data[i]=c.rgbBlue;
			}
		}
    } else {
        return 0;
    }
	
    cp->tdx=img->x1-img->x0;
	cp->tdy=img->y1-img->y0;

    tcp->csty=0;
    tcp->prg=0;
    tcp->mct=img->numcomps==3?1:0;
    tcp->tccps=(j2k_tccp_t*)calloc(img->numcomps*sizeof(j2k_tccp_t),1);

    int ir=0; /* or 1 ???*/

    for (i=0; i<img->numcomps; i++) {
        tccp=&tcp->tccps[i];
        tccp->csty=0;
        tccp->numresolutions=6;
        tccp->cblkw=6;
        tccp->cblkh=6;
        tccp->cblksty=0;
        tccp->qmfbid=ir?0:1;
        tccp->qntsty=ir?J2K_CCP_QNTSTY_SEQNT:J2K_CCP_QNTSTY_NOQNT;
        tccp->numgbits=2;
        tccp->roishift=0;
        j2k_calc_explicit_stepsizes(tccp, img->comps[i].prec);
    }

    BYTE* dest=(BYTE*)calloc(tcp->rates[tcp->numlayers-1]+2,1);
    long len = j2k_encode(img, cp, dest, tcp->rates[tcp->numlayers-1]+2);

    if (len==0) {
		strcpy(info.szLastError,"J2K failed to encode image");
    } else {
		hFile->Write(dest, len, 1);
	}
	
	free(dest);
	j2k_destroy(&img,&cp);

	return (len!=0);
}
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;
}
Exemple #7
0
bool CxImageGIF::Encode(CxFile * fp)
{
	if (EncodeSafeCheck(fp)) return false;

	GifFileType *GifFile = NULL;
	ColorMapObject *OutputColorMap = NULL;
	int i, ColorMapSize;

	if(head.biBitCount != 8)
	{
		if(head.biBitCount < 8)IncreaseBpp(8);
		else DecreaseBpp(8, true);
	}

	try
	{
		GifFile = EGifOpen(fp, writeCxFile);

		ColorMapSize = head.biClrUsed;
		OutputColorMap = MakeMapObject(ColorMapSize, NULL);

		RGBQUAD* pPal = GetPalette();
		for(i=0; i<ColorMapSize; ++i) 
		{
			OutputColorMap->Colors[i].Red = pPal[i].rgbRed;
			OutputColorMap->Colors[i].Green = pPal[i].rgbGreen;
			OutputColorMap->Colors[i].Blue = pPal[i].rgbBlue;
		}

		EGifPutScreenDesc(GifFile, head.biWidth, head.biHeight, OutputColorMap->ColorCount, info.nBkgndIndex== -1 ? 0 : info.nBkgndIndex, OutputColorMap);

		FreeMapObject(OutputColorMap);
		OutputColorMap = NULL;

		if(info.nBkgndIndex != -1)
		{
			unsigned char ExtStr[4] = { 1, 0, 0, info.nBkgndIndex };
			EGifPutExtension(GifFile, GRAPHICS_EXT_FUNC_CODE, 4, ExtStr);
		}

		EGifPutImageDesc(GifFile, 0, 0, head.biWidth, head.biHeight, FALSE, NULL);

		for (i = 0; i < head.biHeight; i++)
			EGifPutLine(GifFile, GetBits(head.biHeight - i - 1), head.biWidth);

		EGifCloseFile(GifFile);
		GifFile = NULL;
	} catch (int errid) {
		strncpy(info.szLastError,GifGetErrorMessage(errid),255);
		if(OutputColorMap)
		{
			FreeMapObject(OutputColorMap);
			OutputColorMap = NULL;
		}
		if(GifFile)
		{
			EGifCloseFile(GifFile);
			GifFile = NULL;
		}
		return false;
	} catch (char *message) {
		strncpy(info.szLastError,message,255);
		if(OutputColorMap)
		{
			FreeMapObject(OutputColorMap);
			OutputColorMap = NULL;
		}
		if(GifFile)
		{
			EGifCloseFile(GifFile);
			GifFile = NULL;
		}
		return false;
	}

	return true;
}