We've come across some TIFF images that are type 6 OJPEG compressed, many have the same BitsPerSample of "8 8 8" and work fine.
However, now and then we see ones that have a BitsPerSample value of say "8 25608 0". I'm wondering if this is even possible and if not whether its a bug in the system that generated the TIFFs. If it is could they potentially be fixed by simply modifying the tag so the BitsPerSample is "8 8 8"?
Currently I've only found one tool (LEAD) that can handle them by converting them to uncompressed TIFFs, obviously I've no idea how it does this and it's a big overhead just to solve an issue with a very small minority of images.
Has anyone come across this or have more knowledge than me regarding whether this is simple or complicated to fix, so far my attempts at poking around in the Libtiff.net code haven't been very fruitful!
Cheers
UPDATE: Using litiff.net with something as simple as this:
static void Main(string[] args)
{
using (Tiff image = Tiff.Open(args[0], "r"))
{
FieldValue[] value = image.GetField(TiffTag.IMAGEWIDTH);
int width = value[0].ToInt();
Console.WriteLine(string.Format("Width = {0}", width));
}
}
Results in (obviously skipped the exception handling!):
ReadDirectory: Warning, 10.TIF: unknown field with tag 33000 (0x80e8) encountered 10.TIF: Cannot handle different per-sample values for field "BitsPerSample"
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object. at tifftest.Program.Main(String[] args) in C:\tiffstuff\tifftest\tifftest\Program.cs:line 15 Segmentation fault
I'm now getting it to bypass the check and assume 8 for "BitsPerSample" however I'm now trying to extract the image to save as a BMP using the example on the bitmiracle site:
using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte[] bits = new byte[bmpdata.Stride * bmpdata.Height];
for (int y = 0; y < bmp.Height; y++)
{
int rasterOffset = y * bmp.Width;
int bitsOffset = (bmp.Height - y - 1) * bmpdata.Stride;
for (int x = 0; x < bmp.Width; x++)
{
int rgba = raster[rasterOffset++];
bits[bitsOffset++] = (byte)((rgba >> 16) & 0xff);
bits[bitsOffset++] = (byte)((rgba >> 8) & 0xff);
bits[bitsOffset++] = (byte)(rgba & 0xff);
}
}
System.Runtime.InteropServices.Marshal.Copy(bits, 0, bmpdata.Scan0, bits.Length);
bmp.UnlockBits(bmpdata);
bmp.Save("c:\\tiffstuff\\TiffTo24BitBitmap.bmp");
}
I obviously get the OJPEG warning and then the following: OJPEGReadHeaderInfoSecTablesQTable: Missing JPEG tables
The resultant image is just 100% green.
Am I just too far out of my depth in terms of fixing this? I know the JPEG is in there somewhere just can't seem to get at it and decompress it successfully :-(
A bit depth of 25608 is definitely wrong. JPEG compression never uses a bit depth other than 8 bits per pixel. There are other image formats that can use 16 or even 32 bits per pixel, but that is as high as it gets for any normal application.
In JPEG there is RGB images, i.e. "8 8 8", CMYK images, i.e "8 8 8 8", and monochrome images, ie. "8".
It's possible that the images are CMYK, and that the software that you use doesn't support that. In that case you need to convert them to RGB to use them with that software.
If the images are RGB then the tag is simply corrupt, and fixing it would make the images work just fine. (Assuming of course that there isn't anything else that is also currupted.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With