Verifying the Bit Order of a tiff...

I’m working on a simple preflighting script that checks tiff files and verifies a few things. The script needs to check 1) the color mode is CMYK, 2) The file has no alpha channels, 3) the correct ICC profile is embedded in the file, and 4) the file was saved with LZW compression, with IBM bit order. One of the goals of this project is to verify the tiffs without using Photoshop, and so far I’ve used the Finder, ImageEvents/SIPS, and tiffutil to get everything I need, except I haven’t figured out how to verify the bit order.

I think I’ve heard somewhere that bit order doesn’t matter anymore, but I still need to check for it. Any ideas? Thanks.

Luckilly, this is the easiest one (though I don’t know if it does work for all TIFF versions):

byteOrderIsIBM(alias "path:to:file.tif") --> true

to byteOrderIsIBM(f)
	try
		(read f for 2) is "II"
	on error
		error "Empty file!"
	end try
end byteOrderIsIBM

(“II” is Intel, “MM” is Motorola, or just PC vs Mac)

Thanks, jj. Actually, I didn’t know you can read a tiff file like that, so I learned a couple of things. Reading the file can be useful, assuming you can understand the gibberish it returns :wink:

Yes, just like Photoshop does :wink:
http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf

Thanks for that document. Now here’s another challenge: Without opening in Photoshop, is there a way to find out if a tiff has layers?

Hey, Carl! The answer is “YES”, but I don’t know how to do it… :lol:
If you are good interpreting specs, you can try it yourself. Basically, a TIFF has a header which identifies it as a TIFF, and a pointer to the first IFD, which is a field its own info and a map of bits, and a pointer to another IFD (if there are more of these).
But perhaps it would be better if you knew C or something more robust for this kind of operation… I think AppleScript handles better simple things as read-first-two-bytes-of-file… :rolleyes:

Bump.

I made some progress that I thought I’d post. I found the document TIFFphotoshop.pdf
that specifies the tag that has the layer and mask information. So, as far as I can tell, if this tag exists, then there are layers. The tag is 37724 (935C.H) . The tags in a tiff can be read with the -dump option of the tiffutil command.

This will return true or false:

do shell script "tiffutil -dump /path/to/MyTiff.tif" ) contains "37724"

So I made some progress. Now, the problem I’m having is that if you have a tiff larger than a few megs, it bombs the AppleScript, because (I’m assuming) the result of the -dump is so huge (plus, it takes forever). So that’s where I’m at now…stay tuned…

Then, this may do the job:

try
	do shell script "tiffutil -dump /path/to/file.tif | grep -e 37724 | cut -c 1-5"
	set hasLayers to result is "37724"
on error
	set hasLayers to false
end try

hasLayers

I’ve never used grep before, but I see. This works without bombing the script, so that’s good. It still takes around 5 minutes for a 7 meg file, though.

Thanks again, as usual 8)

Progress…

Yes. Seems that tiffutil is “slow” and “grep” is super-slow, since it must read 23MB of data of tiffutil’s output over my 9MB tif-test-file…
Here is a workaround, not very smart but faster. It requires ImageMagick: http://www.imagemagick.orghttp://www.macupdate.com/info.php/id/12447

try
	do shell script "/usr/local/bin/identify /path/to/file.tif | sh"
	error "NO"
on error msg
	set hasLayers to msg contains "37724"
end try

Carl,

I did a project last year using David Llyod’s Image Info. Since I don’t remember what I ate for breakfast, I can’t tell you if It was fast…but from the times you are posting, I think It’s much faster than your current procedure.

You can find it here:
http://www.kanzu.com/

Hey guys, it’s a happy Friday!

I’ve learned that the section of a tiff’s source that describes the Photoshop-specific image data starts with a character string of “Adobe Photoshop Document Data Block.” This section only exists if there is layer, layer mask, pattern, and/or annotation. (I think I explained that right. It’s all explained in TIFFPhotoshop.pdf that I have a link for above).

Once I found that out, it became simple:

set layers to ((read myTiff) contains "Adobe Photoshop Document Data Block")

Result: true or false

So that’s the gist of what I needed. 8)

Carl,
Did you get over the speed issue?

Sorry for the delay, and scratch what I wrote in my last post. That method doesn’t work at all on large files. I found I can get what I need with grep:

try
   set layers to (do shell script "grep -c MIB8ryaL " & myTiff) --true
on error
   set layers to false
end try

“MIB8ryaL” is another string of text that exists if there are layers. The “-c” option will get the count of how many times MIB8ryaL exists in the file, so if it returns “0,” then there are no layers. Anything other than 0 means there are layers. The problem I had with this, is that if it returns “0” when used in an Applescript, the AS will return an error, rather than returning “0.” So I placed the code in a Try block.

It’s pretty fast. A normal-sized tiff (20-30 mbs) takes a second or less, while one of my huge test tiffs (780 mbs) took ~30 seconds.