I know, it’s passé to cuss out Microsoft, but I’ve got something going on at work right now that is driving me crazy, and I just have to vent.
There’s an internet standard called MIME that was designed to help various systems exchange files. One key part of MIME is the “content-type”. With a content-type, you can safely interpret a stream of raw data — so you wouldn’t try showing someone a picture as if it were text, for example. This stuff all happens pretty automatically for you when you are working on your own computer, but correct content-typing is critical to exchanging files between systems.
OK, so when you write a web application where someone uses a web browser to upload files, the browser tells the server the content-type of each file that it uploads. Now, here’s the rub. For some reason, Microsoft Internet Explorer describes all JPEG image files as type “image/pjpeg,” despite the fact that JPEGs actually come in two types, “image/pjpeg” (Progressive JPEG) and “image/jpeg” (standard JPEG). The difference is important, because many applications which handle JPEG images with no problem cannot handle Progressive JPEGs. In fact, in my case the application which ultimately uses these images completely crashes if it tries to read a Progressive JPEG.
So, as much as I would like to use the MIME type of uploaded images to warn users that they are uploading an unsupported file type, I can no longer do this, because Microsoft incorrectly types the uploaded files as PJPEG even when they aren’t. I have to accept the PJPEG type, because most of my users will be using this browser. So now I have to figure out some back-end process to re-save all uploaded JPEGs as non-progressive JPEGs, just in case. Yuk.
I’ve fixed this once before using ImageMagick and JMagick, but I really wanted to keep JMagick out of this application, because its complicated to make the application portable while depending on the C++ libraries that JMagick links to. Any Java ImageIO specialists out there know the trick? I’ve looked at the Metadata facility, but it looks pretty hairy.
It turns out, perhaps unsurprisingly, that asking Java to save images as JPEG does not save them as progressive JPEG. So, instead of writing the uploaded bytes straight to disk, I read them in using ImageIO, and then use ImageIO to write them as a JPEG. This seems to circumvent the risk of accidentally getting progressive JPEGs into the system, and was actually pretty easy to do. The Metadata is definitely hairy, and I’m glad I didn’t have to make changes to it to save the files differently.