This is the "Image File Directory" parser that turns the color-DNG file into a Monochrome-Linear file.
BLOCK DATA DNGINIT
C+++ BEGIN / CMDNGTAGS/
INTEGER* 4 DNGTAGS
PARAMETER ( DNGTAGS= 49)
INTEGER* 2 IFD0KEEP, TAGCODES
CHARACTER* 64 TAGNAMES
COMMON/ CMDNGTAGS/ TAGNAMES( DNGTAGS),
1 IFD0KEEP( DNGTAGS), TAGCODES( DNGTAGS)
C--- END / CMDNGTAGS
DATA IFD0KEEP/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1,
1 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
1 1/
DATA TAGCODES/
1 Z'00FE', Z'0100', Z'0101', Z'0102', Z'0103',
1 Z'0106', Z'010F', Z'0110', Z'0111', Z'0112',
1 Z'0115', Z'0116', Z'0117', Z'011A', Z'011B',
1 Z'011C', Z'0128', Z'0131', Z'013B', Z'828D',
1 Z'828E', Z'8298', Z'8769', Z'882B', Z'9003',
1 Z'920E', Z'920F', Z'9210', Z'9216', Z'C612',
1 Z'C614', Z'C619', Z'C61A', Z'C61D', Z'C61F',
1 Z'C620', Z'C621', Z'C622', Z'C623', Z'C624',
1 Z'C628', Z'C62B', Z'C62C', Z'C62D', Z'C62F',
1 Z'C632', Z'C635', Z'C65A', Z'C65B'/
DATA TAGNAMES/
1 'GENERAL INDICATOR', 'NUMBER COLUMNS', 'NUMBER OF ROWS',
1 'BITS PER SAMPLE', 'COMPRESSION',
1 'PHOTOMETRIC INTERPRETATION (MOSAIC/LINEAR)', 'MAKE', 'MODEL',
1 'STRIPOFFSET (START OF IMAGE DATA)',
1 'ORIENTATION ( 01= H, 02= V)', 'SAMPLES PER PIXEL',
1 'ROWS PER STRIP', 'STRIP BYTE COUNT', 'X RESOLUTION',
1 'Y RESOLUTION', 'PLANAR CONFIGURATION', 'RESOLUTION UNIT',
1 'SOFTWARE, NAME AND VERSION', 'ARTIST',
1 'CFAREPEATPATTERN', 'CFAPATTERN', 'COPYRIGHT',
1 'POINTER TO EXIF IFD', 'SELF TIME MODE',
1 'DATE_TIME_ORIG', 'X FOCAL PLANE RESOLUTION',
1 'Y FOCAL PLANE RESOLUTION', 'FOCAL PLANE RESOLUTION UNIT',
1 'TIFF STANDARD', 'DNG VERSION', 'UNIQUE CAMERA MODEL',
1 'BLACKLEVELREPEAT', 'BLACK LEVEL', 'WHITE LEVEL',
1 'DEFAULT CROP ORIGIN', 'DEFAULT CROP SIZE',
1 'COLORMATRIX 1', 'COLORMATRIX 2', 'CAMERACALIBRATION',
1 'CAMERACALIBRATION 2', 'AS SHOT NEUTRAL',
1 'BASELINENOISE', 'BASELINESHARPNESS', 'BAYER GREEN SPLIT',
1 'CAMERA SERIAL NUMBER', 'ANTIALIASSTRENGTH',
1 'MAKERNOTESAFETY', 'CALIBRATION ILLUMINANT1',
1 'CALIBRATION ILLUMINANT2'/
END
INTEGER* 4 FUNCTION IFDCONVERT( IFDTABLE, IFDTABLE4, IFDENTRIES)
IMPLICIT NONE
INTEGER* 2 IFDTABLE( 6, IFDENTRIES)
INTEGER* 4 IFDTABLE4( 3, IFDENTRIES)
C+++ BEGIN / CMDNGTAGS/
INTEGER* 4 DNGTAGS
PARAMETER ( DNGTAGS= 49)
INTEGER* 2 IFD0KEEP, TAGCODES
CHARACTER* 64 TAGNAMES
COMMON/ CMDNGTAGS/ TAGNAMES( DNGTAGS),
1 IFD0KEEP( DNGTAGS), TAGCODES( DNGTAGS)
C--- END / CMDNGTAGS
INTEGER* 4 OLDTAGS, NEWTAGS, TAGINDEX, TAGLIST, TAGSEARCH, INDEX
LOGICAL* 4 FOUND
C SEARCH THROUGH ALL OF THE TAGS PASSED IN.
DO 5 OLDTAGS= 1, IFDENTRIES
C IDENTIFY THE TAG FROM THE KNOWN LIST.
TAGSEARCH= 0
10 CONTINUE
TAGSEARCH= TAGSEARCH+ 1
FOUND= TAGCODES( TAGSEARCH) .EQ. IFDTABLE( 1, OLDTAGS)
IF( ( .NOT. FOUND) .AND. TAGSEARCH .LT. DNGTAGS) GO TO 10
IF( FOUND .AND. IFD0KEEP( TAGSEARCH) .NE. 0) THEN
C KEEP THE TAG.
WRITE( *, *) ' KEEPING TAG ', OLDTAGS
NEWTAGS= NEWTAGS+ 1
IF( TAGCODES( TAGSEARCH) .EQ. Z'0106') THEN
C 6 0106: PHOTOMETRIC INTERP: 8023 FOR COLOR; 884C FOR LINEAR
IFDTABLE( 5, OLDTAGS)= Z'884C'
C 17 0128: RESOLUTION UNIT. 02. THE UNIT OF RESOLUTION FOR X AND FOR Y.
ELSE IF( TAGCODES( TAGSEARCH) .EQ. Z'0128') THEN
IFDTABLE( 5, OLDTAGS)= 1
C 28 9210: FOCAL PLANE RESOLUTION UNIT, 0002. (LOC 0156 SET TO 1?)
ELSE IF( TAGCODES( TAGSEARCH) .EQ. Z'9210') THEN
IFDTABLE( 5, OLDTAGS)= 1
C 30 C612: DNG VERSION: 4 BYTES 01 04 00 00 (CHANGE LOC 16F TO 01)
ELSE IF( TAGCODES( TAGSEARCH) .EQ. Z'C612') THEN
IFDTABLE( 5, OLDTAGS)= Z'0101'
C 33 C61A: BLACK LEVEL: 1 WORD, 005C
ELSE IF( TAGCODES( TAGSEARCH) .EQ. Z'C61A') THEN
C IFDTABLE( 5, OLDTAGS)= 1
C 34 C61D: WHITE LEVEL: 1 WORD, 3FFF
ELSE IF( TAGCODES( TAGSEARCH) .EQ. Z'C61D') THEN
IFDTABLE( 5, OLDTAGS)= Z'7FFF'
END IF
IFDTABLE( 1, NEWTAGS)= IFDTABLE( 1, OLDTAGS)
IFDTABLE( 2, NEWTAGS)= IFDTABLE( 2, OLDTAGS)
IFDTABLE( 3, NEWTAGS)= IFDTABLE( 3, OLDTAGS)
IFDTABLE( 4, NEWTAGS)= IFDTABLE( 4, OLDTAGS)
IFDTABLE( 5, NEWTAGS)= IFDTABLE( 5, OLDTAGS)
IFDTABLE( 6, NEWTAGS)= IFDTABLE( 6, OLDTAGS)
ELSE
WRITE( *, *) ' ELIMINATE TAG ', OLDTAGS
END IF
5 CONTINUE
DO 20 INDEX= NEWTAGS+ 1, IFDENTRIES
WRITE( *, *) ' ZERO TAG ', INDEX
IFDTABLE( 1, INDEX)= 0
IFDTABLE( 2, INDEX)= 0
IFDTABLE( 3, INDEX)= 0
IFDTABLE( 4, INDEX)= 0
IFDTABLE( 5, INDEX)= 0
IFDTABLE( 6, INDEX)= 0
20 CONTINUE
IFDCONVERT= NEWTAGS
RETURN
END
The Mosaic algorithm shown here is best for the O56, the Yellow Y48 filter- uses a routine that does the demosaic on the three channels as they are more balanced. The O56 is where things got into the two-channel possibility. I will look at a Yellow-3 Y48 and an R60.
But that's enough code written for one day. Takes less time than you m ight think.