2005.10.27 06:40 "[Tiff] How located pixels with BitsPerSample not bound to byte?", by Шебеко Евгений

2005.10.27 13:57 "Re: [Tiff] How located pixels with BitsPerSample not bound to byte?", by Frank Warmerdam

On 10/27/05, Шебеко Евгений <shebeko@mail.ru> wrote:

If we talking about testing exotic images.

Look at the flower-rgb-contig-12.tif from the test images. It have RGB,Uncompressed, PlanarConfig=Continue, and BitsPerSample=12

How the pixels are located inside a strip in such case? I really cann't understand :)

Is it correct?

  Bytes:       0   |    1    |    2   |   3    |   4
  Bits :   76543210|7654|3210|76543210|76543210|7654|3210
  Pixels:  rrrrrrrr|rrrr|gggg|gggggggg|bbbbbbbb|bbbb|rrrr|
  Samples:   hiR   |lowR|hiG |  lowG  |  hiB   |lowB| hiR

Eugene,

I thought it should work as you have shown, but when I review my code it seems the first byte will be the low order 8bits of red, not the high (and so forth). I am including my code for arbitrary unpacking of odd bit data into words though it may be a bit opaque. I believe Bob uses a more efficient solution.

/* -------------------------------------------------------------------- */
/*      Handle 1-32 bit integer data.                                   */
/* -------------------------------------------------------------------- */

    else
    {

        int     iBit, iPixel, iBitOffset = 0;
        int     iPixelBitSkip, iBandBitOffset, iX, iY, nBitsPerLine;

        if( poGDS->nPlanarConfig == PLANARCONFIG_CONTIG )
        {
            iPixelBitSkip = poGDS->nBands * poGDS->nBitsPerSample;
            iBandBitOffset = (nBand-1) * poGDS->nBitsPerSample;
        }
        else
        {
            iPixelBitSkip = poGDS->nBitsPerSample;
            iBandBitOffset = 0;
        }

        // bits per line rounds up to next byte boundary.
        nBitsPerLine = nBlockXSize * poGDS->nBitsPerSample;
        if( (nBitsPerLine & 7) != 0 )
            nBitsPerLine = (nBitsPerLine + 7) & (~7);

        iPixel = 0;
        for( iY = 0; iY < nBlockYSize; iY++ )
        {

            iBitOffset = iBandBitOffset + iY * nBitsPerLine;

            for( iX = 0; iX < nBlockXSize; iX++ )
            {
                int nOutWord = 0;

                for( iBit = 0; iBit < poGDS->nBitsPerSample; iBit++ )
                {
                    if( poGDS->pabyBlockBuf[iBitOffset>>3]
                        & (0x80 >>(iBitOffset & 7)) )
                        nOutWord |= (1 << (poGDS->nBitsPerSample - 1 - iBit));
                    iBitOffset++;
                }

                if( eDataType == GDT_Byte )
                    ((GByte *) pImage)[iPixel++] = nOutWord;
                else if( eDataType == GDT_UInt16 )
                    ((GUInt16 *) pImage)[iPixel++] = nOutWord;
                else if( eDataType == GDT_UInt32 )
                    ((GUInt32 *) pImage)[iPixel++] = nOutWord;

            }
        }
    }

Best regards,
--

---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, warmerdam@pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Programmer for Rent