2005.05.24 06:27 "[Tiff] Question about Jpeg-in-tiff, JPEG IN TIFF created by libtiff can't be read by acdsee", by Kelvin Zhong

2005.05.25 04:52 "Re: [Tiff] Question about Jpeg-in-tiff, J PEG IN TIFF created by libtiff can't be r ead by acdsee", by Kelvin Zhong

Windows Imaging is half a century behind, it's still trying to make sense of original old-style TIFF 6.0 jpeg-in-tiff, while the rest of the planet agrees new-style compression 7 as specificied in specification supplement 2 is the way to go. As to ACDSEE, I don't know.

  1. what libtiff doing(write) with the JPEG-in-TIFFs as i described meet the TIFF Specification (standard) ?

Yes, it is. The specification, I mean to include the supplements. See http://www.awaresystems.be/imaging/tiff/faq.html#q4 for the full list of URLs to the specification. I intentionally include a pointer to Tom's original TT2 there, even though this is absorbed in supplement 2, because that original includes a lengthy description of why the format that Window Imaging is trying to honour is complete shambles and should not be used.

  1. how can i do some modification with the libtiff library ,just make it can write the jpeg data as a single strip.?

Show us your current code. If you use the strip interface, and you need to write a single strip, the modification should probably be as easy as adjusting the rowsperstrip value, I think.

Thanks Joris.

i show you some codes i did with the 24 bitcount Image here:

//dibImage is a class do some operation on DIB data.
         BITMAPINFOHEADER* pBitmapHeaderInfo=dibImage.GetBitmapHeader();
        DIBINFO* pDibInfo=dibImage.GetDIBInfo();
        if( pBitmapHeaderInfo == NULL || pDibInfo == NULL)
                return FALSE;

        uint32 height=pBitmapHeaderInfo->biHeight;
        uint32 width=pBitmapHeaderInfo->biWidth;
        uint16 bitcount=pBitmapHeaderInfo->biBitCount;
        uint16 bitspersample;
        uint16 samplesperpixel;
        uint16 photometric=0;
        uint16 compression;
        uint32 x, y;

        uint16* r=NULL;
        BYTE* buffer=NULL;

        //samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (BYTE)3 : (BYTE)1;
        samplesperpixel = (bitcount == 24)? (BYTE)3 :(BYTE)1;

        bitspersample = bitcount / samplesperpixel;
         photometric = PHOTOMETRIC_YCBCR;// PHOTOMETRIC_RGB;
        compression = COMPRESSION_JPEG;
                // 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);         TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
        uint32 rowsperstrip = TIFFDefaultStripSize(m_tif, (uint32) -1);         TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
        // handle metrics
        TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
        TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, (float)(pBitmapHeaderInfo->biXPelsPerMeter * 254.0 /10000) + 0.5f);
        TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, (float)(pBitmapHeaderInfo->biYPelsPerMeter * 254.0 /10000) + 0.5f);
        TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression);
        TIFFSetField(m_tif, TIFFTAG_JPEGQUALITY, 100);//m_nJpegCompressQuality);
        //TIFFSetField(m_tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
        TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, height);//((7+rowsperstrip)>>3)<<3);
  ..........
        buffer = (BYTE*)malloc(pDibInfo->dwEffWidth);
        if ( buffer == NULL)
                throw _T("Not enough memory");
        for (y = 0; y < height; y++) {
                // get a pointer to the scanline
             memcpy(buffer, pDibInfo->pImage + (height - y - 1)*pDibInfo->dwEffWidth, pDibInfo->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);
                        buffer = NULL;
                        throw _T("Error in writing!");
                }
        }
        free(buffer);
        buffer =NULL;

When i use TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, height);

it seems the jpeg-data was writed as a single strip.but ACDSEE still can't opened it.

I tried to save the JPEG-IN-TIFF as
   photometric = PHOTOMETRIC_YCBCR;// PHOTOMETRIC_RGB;
   compression = COMPRESSION_JPEG;
but all the image i tried to create can't be opened by ACDSEE,

I didn't know where the problem is, probably would be "TIFFWriteScanline" function?

Or is there another way could do it?

such as "Attach" & "Detach" the JPEG-data into(out of) TIFF file as a single strip(or tile), without doing compress or decompress the image data. thus save the time & image quality ,is it possible?

does anyone do some research on it?
I would be very appreciate to you for sharing some knowledge with me,

Thanks in advance.

Kingore@126.com