示例#1
0
/**
 * Blends the alpha channel and the alpha palette with the pixels. The result is a 24 bit image.
 * The background color can be selected using SetTransColor().
 */
void CxImage::AlphaStrip()
{
	bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
	bool bAlphaIsValid = AlphaIsValid();
	if (!(bAlphaIsValid || bAlphaPaletteIsValid)) return;
	RGBQUAD c;
	long a, a1;
	if (head.biBitCount==24){
		for(long y=0; y<head.biHeight; y++){
			for(long x=0; x<head.biWidth; x++){
				c=GetPixelColor(x,y);
				if (bAlphaIsValid) a=(AlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
				a1 = 255-a;
				c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)/255);
				c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)/255);
				c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)/255);
				SetPixelColor(x,y,c);
			}
		}
		AlphaDelete();
	} else {
		CxImage tmp(head.biWidth,head.biHeight,24);
		if (!tmp.IsValid()) return;
		for(long y=0; y<head.biHeight; y++){
			for(long x=0; x<head.biWidth; x++){
				c=GetPixelColor(x,y);
				if (bAlphaIsValid) a=(AlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
				if (bAlphaPaletteIsValid) a=(c.rgbReserved*a)/255;
				a1 = 255-a;
				c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)/255);
				c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)/255);
				c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)/255);
				tmp.SetPixelColor(x,y,c);
			}
		}
		Transfer(tmp);
	}
	return;
}
示例#2
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;
}
示例#3
0
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;
}