| AWARE [SYSTEMS] | Imaging expertise for the Delphi developer | |||||||
![]() |
TIFF and LibTiff Mailing List Archive | |||||||
LibTiff Mailing List
TIFF and LibTiff Mailing List Archive Contact
The TIFF Mailing List Homepage |
2007.10.27 16:40 "tiff reading with libtiff: problems with certain image files", by Tobias EberleHello, the code below reads tiff files and saves the grey scaled pixels into an array. The code works well except for certain images. You can find an example image at: http://stuff.tobiaseberle.de/F2-1.tif The problem arises in the for loop iterating over the pixels: for (unsigned int ii = 0; ii < uiBufferSize; ii+=usSamplesPerPixel) uiBufferSize is too large and my voxel class raises an exception telling that we are out of range. I don't know what is different between this image and other images. Why is the buffer size wrong or lets say different than expected? Thank you for your help, Tobias TIFF *file = TIFFOpen(iter->c_str(), "r"); if (!file) { m_pVoxelField->clear(); throw EFileReaderFileNotFound(*iter); } //get image size unsigned int uiWidth; unsigned int uiHeight; TIFFGetField(file, TIFFTAG_IMAGEWIDTH, &uiWidth); TIFFGetField(file, TIFFTAG_IMAGELENGTH, &uiHeight); if (bFirst) { uiDimX = uiWidth; uiDimY = uiHeight; m_pVoxelField->setDim(uiWidth, uiHeight, uiDimZ); bFirst = false; } if (uiWidth != uiDimX || uiHeight != uiDimY) { m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderTiffFilesDoNotHaveSameImageSize(*iter); } //get bits per sample unsigned short usBitsPerSample; if (TIFFGetField(file, TIFFTAG_BITSPERSAMPLE, &usBitsPerSample) == 0) { m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderTiffUndefinedBitsPerSample(*iter); } unsigned short usExtraSamples; if (TIFFGetField(file, TIFFTAG_EXTRASAMPLES, &usExtraSamples) == 0) { ... } //8bit greyscale or 24bit true color if (usBitsPerSample != 8) { m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderTiffUnsupportedBitsPerSample(*iter); } //get samples per pixel unsigned short usSamplesPerPixel; if (TIFFGetField(file, TIFFTAG_SAMPLESPERPIXEL, &usSamplesPerPixel) == 0) { m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderTiffUndefinedSamplesPerPixel(*iter); } //1 for greyscale, 3 for rgb if (usSamplesPerPixel != 1 && usSamplesPerPixel != 3) { m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderTiffUnsupportedSamplesPerPixel(iter->c_str()); } //get planar config unsigned short usPlanarConfig; if (TIFFGetField(file, TIFFTAG_PLANARCONFIG, &usPlanarConfig) != 0) { if (usPlanarConfig != PLANARCONFIG_CONTIG) { throw EFileReaderTiffUnsupportedPlanarConfig(*iter); } } //get photometric unsigned short usPhotometric; if (TIFFGetField(file, TIFFTAG_PHOTOMETRIC, &usPhotometric) == 0) { m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderTiffUndefinedPhotometricInterpretation(*iter); } if (usPhotometric != PHOTOMETRIC_RGB && usPhotometric != PHOTOMETRIC_MINISBLACK && usPhotometric != PHOTOMETRIC_MINISWHITE) { m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderTiffUnsupportedPhotometricInterpretation(*iter); } //get fill order unsigned short usFillOrder; if (TIFFGetField(file, TIFFTAG_FILLORDER, &usFillOrder) == 0) { //assume correct fill order usFillOrder = FILLORDER_MSB2LSB; } //read in the possible multiple strips int iStripSize = TIFFStripSize(file); int iStripMax = TIFFNumberOfStrips(file); unsigned int uiOffset = 0; unsigned char *pucBuf; //calculate buffer size for the image. unsigned int uiBufferSize = iStripMax*iStripSize; //unsigned int uiBufferSize = uiDimX * uiDimY * usSamplesPerPixel; pucBuf = new unsigned char[sizeof(unsigned char)*uiBufferSize]; if (pucBuf == NULL) { m_pVoxelField->clear(); TIFFClose(file); throw EOutOfMemory(); } for(int iStripCounter = 0; iStripCounter < iStripMax; iStripCounter ++) { //read one strip int iRead = TIFFReadEncodedStrip(file, iStripCounter, pucBuf + uiOffset, iStripSize); if (iRead == -1) { delete[] pucBuf; m_pVoxelField->clear(); TIFFClose(file); throw EFileReaderBadFile(*iter); } uiOffset += iRead; } unsigned int uiX = 0; unsigned int uiY = 0; for (unsigned int ii = 0; ii < uiBufferSize; ii+=usSamplesPerPixel) { unsigned char ucVoxel = pucBuf[ii]; //fillorder if (usFillOrder != FILLORDER_MSB2LSB) { //swap bits: AB -> BA for (unsigned char jj = 0; jj < usSamplesPerPixel; jj++) { unsigned char ucTemp = pucBuf[ii+jj]; pucBuf[ii+jj] <<= 4; ucTemp >>= 4; pucBuf[ii+jj] += ucTemp; } } //photometric interpretation if (usPhotometric != PHOTOMETRIC_RGB) { if (usPhotometric == PHOTOMETRIC_MINISWHITE) { //wrong interpretation, we need 0 = black //-> flip bits ucVoxel = ~ucVoxel; } } else { //greyscale ucVoxel = (pucBuf[ii] + pucBuf[ii+1] + pucBuf[ii+2])/3; } //set voxel m_pVoxelField->setVoxel(uiX, uiY, zz, ucVoxel); //count x and y position uiY = uiY + 1; if (uiY >= uiDimY) { uiY = 0; uiX++; } } delete[] pucBuf; TIFFClose(file); |
|||||||