Article History

Creating custom JPEG files

For creating JPEG files on my deviantART account I started with a simple shell script called png2jpeg. Initially this was to simplify the creation of a JPEG file from my final PNG image, using my custom scan scripts for cjpeg from the Independent JPEG Group. These scan scripts produce JPEG's that load in progressive scans, or at least they do if you use a web browser that's seen a major update in the last 3 years *cough*IE sucks*cough*.

Later I added the ability to write “fake” EXIF data to the JPEG file using EXIFtool. This allows me to add certain ‘tags’ which are read by a lot of graphics software. Digital cameras usually write this data to the JPEG file when they take a photo. I wanted my film photographs to have the same sort of information, and this is the solution I came up with.

png2jpeg:

#!/bin/sh

FILE=$1
BASE=`echo "$FILE" | sed -e 's|^.*/||;s|\.png$||'`
OUT="$BASE.jpeg"
shift

TAGS=$TAGS`grep '^#@' .$BASE.tags | sed -e 's|^#@[ ][ ]*||' | while read tag; do echo " $tag"; done`
echo tags $TAGS

JOPTS="-opt -pro -dct float -sample 2x2 -scans $HOME/cjpeg-${SPACE:-rgb}.scan"
EOPTS="-v -overwrite_original -P"`for t in default $TAGS; do echo -n " -@ .tags/$t"; done`" -@ .$BASE.tags $EXIF"

echo "pngtopnm \"$FILE\" | cjpeg $JOPTS $@ > \"$OUT\""
pngtopnm "$FILE" | cjpeg $JOPTS $@ > "$OUT"

echo "exiftool $EOPTS \"$OUT\""
exiftool $EOPTS "$OUT"

ls -lh "$FILE" "$OUT"

Firstly you'll need some scan scripts.

cjpeg-rgb.scan:

# Y DC coefficients, except 1 lsb
0:      0-0,    0, 1 ;

# Cr and Cb DC coefficients, except 2 lsb's
1:      0-0,    0, 2 ;
2:      0-0,    0, 2 ;

# Some Y AC coefficients, except 2 lsb's
0:      1-2,    0, 2 ;

# Some Cr and Cb coefficients
2:      1-63,   0, 2 ;
1:      1-63,   0, 2 ;

# Rest of the Y AC coefficients
0:      3-9,    0, 2 ;

1,2:    0-0,    2, 1 ;

# Rest of the Cr and Cb AC coefficients
0:      10-63,  0, 2 ;

1:      1-63,   2, 1 ;
2:      1-63,   2, 1 ;

# Fill in the the 2nd-last lsb of the Y coefficients
0:      1-63,   2, 1 ;

1:      1-63    1, 0 ;
2:      1-63    1, 0 ;

0:      1-63    1, 0 ;

cjpeg-grey.scan:

0:      0-0,    0, 1 ;

0:      1-5,    0, 2 ;
0:      6-63,   0, 2 ;

0:      0-0,    1, 0 ;

0:      1-63,   2, 1 ;
0:      1-63,   1, 0 ;

Then you'll need some tag files in the .tags directory. Start with some defaults.

.tags/default:

-Artist="Joe Blogs <joe@somewhere.com>"
-Copyright="Copyright (c) 2005-2006 Joe Blogs <joe@somewhere.com>"
-ColorSpace="sRGB"

Some tags for your camera.

.tags/Ricoh:

-Make=Ricoh
-Model="KR-5 SuperII"
-SceneType="Directly photographed"
-ExposureProgram=Manual
-ExifIFD:MeteringMode="Center-weighted average"

And a lens or two.

.tags/Rikenon55:

-ExifIFD:Lens="XR Rikenon 1:2.2 55mm"
-FocalLength=55
-FocalLengthIn35mmFormat=55

.tags/ZenitarFE:

-ExifIFD:Lens="Zenitar-K"
-FocalLength=16
-FocalLengthIn35mmFormat=16

Plus some film. EXIF doesn't appear to have a field for film name, just speed.

.tags/Superia400:

-ExifIFD:ISO=400
-ISOSetting=400
-ExposureIndex=400

.tags/Velvia50:

-ExifIFD:ISO=50
-ISOSetting=50
-ExposureIndex=50

Finally you make a tag file for each photo.

.BathtimeIsFun.tags:

#@ Ricoh
#@ Rikenon55
#@ PanFplus50
-ExposureTime="1/125"
-FNumber=5.6
-DateTimeOriginal="2006:06:18 20:00:00"
-XResolution=200
-YResolution=200

The first three lines here are treated as comments by EXIFtool, but are extracted by the png2jpeg shell script. They reference the tag files supplied above. Then it's the remaining tags for this specific photo. Most software only reads a handful of the most interesting tags anyway. Plus, a lot of the available tags are aren't applicable to film photography anyway.

That's all for now.