A little while ago I wrote about implementing fast JPEG encoding on an Analog Devices Blackfin. See the original post here:
Since then I’ve moved to a new hardware platform, with a different blackfin processor and a different image sensor, which has caused me to revisit this code. I found that with the previous code, image quality wasn’t as good as I thought it should be. Sometimes the jpeg image looked a little blocky, or pixelated. Not a lot, but a little bit, enough to notice.
Some digging revealed that it seemed to be related to the DCT (discrete cosine transform) function. In the Surveyor code there are two DCT functions. One, called DCT, is written in C. The other, called r8x8dct, is written in assembler by Analog Devices. By default the jpeg encoder uses the assembler version, and rightfully so, because it’s a lot faster. But I found that when I switched to using the C “DCT” function, image quality was improved, and the jpg images looked like I’d expect them to.
As a result, I wrote an assembler implementation of the C “DCT” function, which is functionally identical to the C code, but a great deal faster. For my 752 x 512 YUV image, these are the speeds I measured for jpeg encoding:
- Using DCT, C function: 138 ms
- Using DCT, my new assembler function: 92 ms
- Using DCT, Analog Devices assembler function: 90 ms
You can see that my DCT assembler function is not quite as fast as the Analog Devices one. But it’s very close; only 2 ms difference. Close enough! The new assembler DCT function is called jpegdct. I’ve revised the .zip file to remove the Analog Devices assembler function, and use my new one. This also has the side benefit that all of the source files are now under the GPL license. The new files are here:
So there we have it. A fast JPEG encoder, fully GPL, and improved image quality. What more could we wish for?