12-bit JPEG has been around for a long time. Proprietary.
Best thing about DNG on my M9, M8, and M Monochrom: I do not have to deal with Huffman code and Discrete Cosine Transforms just to read an image into memory.
SUBROUTINE FILELD( FILE)
IMPLICIT NONE
C THIS IS THE KEY ROUTINE THAT READS IN DNG FILES, CALLS THE CONVERSION
C ROUTINES, AND OUTPUTS THE NEW DNG FILES.
CHARACTER* ( *) FILE
INCLUDE 'GRAPH.FI'
INCLUDE 'GRAPHAPI.FI'
INCLUDE 'FSUBLIB.FI'
C+++ BEGIN/ CMMDNG/
INTEGER* 4 MMCOLUMNS, MMROWS, MMSIZE
PARAMETER ( MMCOLUMNS= 5216, MMROWS= 3472)
PARAMETER ( MMSIZE= MMCOLUMNS* MMROWS* 2)
INTEGER* 4 MMSTART, DNGSIZE
COMMON/ CMMDNG/ MMSTART, DNGSIZE
C--- END/ CMMDNG/
C+++ BEGIN / CMLUNM/
INTEGER* 4 LUINPUT, LULIST, LUTEMP, LURESFILE, LUOUTPUT
COMMON/ CMLUNM/ LUINPUT, LULIST, LUTEMP, LURESFILE, LUOUTPUT
C--- END / CMLUNM/
C+++ BEGIN / CMBUFR/
C BUFFER COMMON BLOCK.
INTEGER* 4 MXBFSZ, MXRCSZ, MAXHEX, RECRDS, IFD0ENTRIES
PARAMETER ( MXRCSZ= 4096, RECRDS= 24576)
PARAMETER ( MXBFSZ= MXRCSZ* RECRDS- 1, MAXHEX= 16384)
PARAMETER ( IFD0ENTRIES= 49)
INTEGER* 4 NXTBYT, NXTRCD, BFRLEN
INTEGER* 4 HEXBGN, HEXLEN
INTEGER* 1 BUFFER, DNGIMAGE
COMMON/ CMBUFR/ BUFFER( 0: MXBFSZ), DNGIMAGE( 0: MXBFSZ),
1 NXTBYT, BFRLEN, NXTRCD,
1 HEXBGN( MAXHEX), HEXLEN( MAXHEX)
CHARACTER* 1 BUFSTR( 0: MXBFSZ)
EQUIVALENCE ( BUFSTR, BUFFER)
CHARACTER* 12 IFD0TAGS( IFD0ENTRIES)
INTEGER* 4 TAGSI4( 3, IFD0ENTRIES)
INTEGER* 2 TAGSI2( 6, IFD0ENTRIES)
INTEGER* 2 TAGSI1( 12, IFD0ENTRIES)
EQUIVALENCE ( BUFFER( 10), IFD0TAGS, TAGSI4, TAGSI2, TAGSI1)
INTEGER* 2 IDENTIFIER, TIFFVERSION
INTEGER* 4 IFD0OFFSET
EQUIVALENCE ( IDENTIFIER, BUFFER( 0))
EQUIVALENCE ( TIFFVERSION, BUFFER( 2))
EQUIVALENCE ( IFD0OFFSET, BUFFER( 4))
C--- END / CMBUFR/
C+++ BEGIN / CMDNGTAGS/
INTEGER* 4 DNGTAGS
PARAMETER ( DNGTAGS= 52)
INTEGER* 2 IFD0KEEP, TAGCODES
CHARACTER* 64 TAGNAMES
INTEGER* 4 TCOLUMNS, TROWS, TBITS, TIMAGESTART, TSUBIFD, TWHITE
INTEGER* 4 TXRES, TYRES, TCFAREPEAT, TCFAPATTERN, TVERS, TBLACK
COMMON/ CMDNGTAGS/ TAGNAMES( DNGTAGS), IFD0KEEP( DNGTAGS),
1 TAGCODES( DNGTAGS), TCOLUMNS, TROWS, TBITS, TIMAGESTART,
1 TSUBIFD, TXRES, TYRES, TCFAREPEAT, TCFAPATTERN, TVERS, TBLACK,
1 TWHITE
C--- END / CMDNGTAGS
INTEGER* 2 DATAVALUE( 0: MXBFSZ/ 2)
EQUIVALENCE ( DATAVALUE, BUFFER)
INTEGER* 1 BUFR2D( MXRCSZ, RECRDS)
EQUIVALENCE ( BUFR2D( 1, 1), BUFFER( 0))
INTEGER* 4 BEGINM8LUT, ENDM8LUT
PARAMETER ( BEGINM8LUT= '00664'X, ENDM8LUT= '00862'X)
INTEGER* 4 BEGINM9LUT, ENDM9LUT
PARAMETER ( BEGINM9LUT= '00614'X, ENDM9LUT= '00812'X)
INTEGER* 4 NEWPTR, OFFSET, POSITN
INTEGER* 2 BYTES, PLNFIL, ASCII1, ASCII2, HANDLE, COUNT
INTEGER* 2 HANDLE2, STATUS
INTEGER* 4 LENGTH, RECORD, I, J, RECORDS, ERRINDEX, INDEX
INTEGER* 2 LENGTH2
INTEGER* 1 ASCIB1( 2), ASCIB2( 2)
EQUIVALENCE ( ASCII1, ASCIB1( 1))
EQUIVALENCE ( ASCII2, ASCIB2( 1))
INTEGER* 4 EXTNSN, NAME, FILSIZ
INTEGER* 4 OLDTAGS, NEWTAGS, TAGINDEX, TAGLIST, TAGSEARCH
INTEGER* 4 SUBTAGS, SUBIFDOFFSET, CURVE
INTEGER* 2 ROOTLN
LOGICAL* 4 PROCESS_ALL
CHARACTER* 80 FILENAME
C EXTERNALS.
INTEGER* 4 STRLEN
INTEGER* 4 SQZSTR
INTEGER* 4 IFDCONVERT, IFDVERS
WRITE( *, 100) 'INPUT CURVE NUMBER (1 TO 8): '
READ( *, 210) CURVE
210 FORMAT( I2)
IF( CURVE .LT. 0 .OR. CURVE .GT. 8) THEN
CURVE= 3
END IF
1000 CONTINUE
WRITE( *, 100) ' FILE TO PROCESS: '
100 FORMAT( A, $)
READ( *, 200) FILE
WRITE( *, *) ' FILE IS "', FILE, '".'
200 FORMAT( A)
LENGTH= STRLEN( FILE)
PROCESS_ALL= LENGTH .EQ. 0
IF( PROCESS_ALL) THEN
WRITE( *, *) ' PROCESS FILES IN DNGFILES.DAT'
OPEN( UNIT= LULIST, FILE= 'DNGFILES.DAT', STATUS= 'OLD')
WRITE( *, *) ' PROCESS FILES IN DNGFILES.DAT'
ELSE
FILENAME= FILE( 1: LENGTH)
END IF
1010 CONTINUE
IF( PROCESS_ALL) THEN
READ( LULIST, 200, END= 1020) FILENAME
LENGTH= STRLEN( FILENAME)
WRITE( *, *) ' FILE= "', FILENAME( 1: LENGTH), '"'
IF( LENGTH .EQ. 0) GO TO 1020
FILE= FILENAME( 1: LENGTH)
END IF
C INIT BUFFER BEGINNING.
NXTBYT= 0
C OPEN FILE.
OPEN( UNIT= LUINPUT, FILE= FILENAME( 1: LENGTH), STATUS= 'OLD',
1 RECORDTYPE= 'FIXED', FORM= 'UNFORMATTED',
2 RECL= MXRCSZ, ERR= 1000)
C IF OPEN FAILED, GO TO NEXT FILE.
WRITE( *, *) ' PROCESSING FILE "', FILENAME( 1: LENGTH), '".'
IF( CURVE .NE. 0) THEN
FILENAME( 1: 1)= 'G'
ELSE
FILENAME( 1: 1)= 'C'
END IF
FILSIZ= 0
C OPEN SUCCESS.
FILSIZ= FILESIZE( LUINPUT)
LENGTH= MXRCSZ
RECORDS= FILSIZ/ MXRCSZ
DO 10 RECORD= 1, RECORDS
READ( LUINPUT)( BUFR2D( I, RECORD), I= 1, LENGTH)
10 CONTINUE
RECORD= 17790
LENGTH= FILSIZ- ( RECORDS* MXRCSZ)
IF( LENGTH .GT. 0) THEN
READ( LUINPUT)( BUFR2D( I, RECORD), I= 1, LENGTH)
END IF
C LENGTH OF BUFFER.
WRITE( *, 310) FILSIZ
310 FORMAT( ' FILESIZE= ', I8)
C MAKE A COPY OF THE DNG IMAGE FROM THE BUFFER.
DO 5 I= 1, FILSIZ
DNGIMAGE( I)= BUFFER( I)
5 CONTINUE
C OPEN THE IFD.
TSUBIFD= -1
OLDTAGS= BUFFER( 8)
OFFSET= 10
NEWTAGS= IFDVERS( BUFFER( OFFSET), BUFFER( OFFSET), OLDTAGS)
C IS THERE A SUBIFD?
IF( TSUBIFD .NE. -1) THEN
CALL IFD_VALUES( BUFFER( OFFSET), BUFFER( OFFSET),
1 OLDTAGS)
C WE NEED THE INFO FROM THE SUBIFD.
OFFSET= TSUBIFD+ 2
SUBTAGS= BUFFER( TSUBIFD)
NEWTAGS= IFDVERS( BUFFER( OFFSET), BUFFER( OFFSET), SUBTAGS)
OLDTAGS= SUBTAGS
END IF
IF( .FALSE.) THEN
CALL FIND_BADLINE( BUFFER( TIMAGESTART),
1 DNGIMAGE( TIMAGESTART),
1 TCOLUMNS, TROWS)
END IF
CALL CONVERT16( BUFFER( TIMAGESTART), TCOLUMNS, TROWS, CURVE)
IF( CURVE .NE. 0) THEN
CALL IFDUPDATE( BUFFER( OFFSET), BUFFER( OFFSET), OLDTAGS)
C BUFFER( OFFSET- 2)= NEWTAGS
END IF
LENGTH= STRLEN( FILENAME)
OPEN( UNIT= LUOUTPUT, FILE= FILENAME( 1: LENGTH),
1 RECORDTYPE= 'FIXED', FORM= 'UNFORMATTED',
2 RECL= MXRCSZ)
LENGTH= MXRCSZ
RECORDS= FILSIZ/ MXRCSZ
LENGTH= MXRCSZ
DO 16 RECORD= 1, RECORDS
WRITE( LUOUTPUT)( BUFR2D( I, RECORD), I= 1, LENGTH)
16 CONTINUE
LENGTH= FILSIZ- ( RECORDS* MXRCSZ)
IF( LENGTH .GT. 0) THEN
WRITE( LUOUTPUT)( BUFR2D( I, RECORD), I= 1, LENGTH)
END IF
CLOSE( UNIT= LUINPUT)
CLOSE( UNIT= LUOUTPUT)
IF( PROCESS_ALL) GO TO 1010
1020 CONTINUE
FILE= FILENAME( 1: 12)
RETURN
END