Jake's description

Home
Up

DiMAGE 5/7 RAW Format Discovery

Header Description (as far as known), for those who like to write a program or play around with it.

Two-byte integers have MSB first, LSB next order.
The RAW files can slightly vary in size.
For the correct offset of the pixel data, examine the header info, or you will end up in a program that fails to interpolate every file correctly.
I had incomplete downloads of raw files which were just a part of the normal size. Still you can interpolate the received parts!
See screenshot in section "D7RAW discontinued:" thumbnail "Pict0005-incomplete.mrw", this file is only 2919256 bytes in size.

In the table below locations and data are in HEX or else, when representing strings, in ASCII.
The HEX prefix 0x has been left out for ease of reading.
Those locations that are not mentioned in the table within the offset from 0000 up to 0100 are holding equal values for the D5 and D7 in all images that I have inspected.

I'd like to thank Patrick for checking the information in the table below and reporting some errors, which have been corrected by now.

Corrections made:

  • the "DCF" string actually starts at offset 0xAA instead of 0xAB
  • the ccd width and height are inverted

    Offset:

    Data:

    0000 00
    0001/0003 4D 52 4D "MRM"
    0006 0007 The Image Offset for the pixel data, can vary:
    BBF8 (example, may vary a little bit)
    (Checked for validation: FileSize = ImageXSize * ImageYSize * 2 + ImageOffset)
    Calculate the index in the file for any pixel at Xposition, Yposition:
  • ImageFileOffset = RawBuffer[0006] * 256 + RawBuffer[0007] + 8;
  • RawIndex = Xposition * 2 + Yposition *(ImageXSize + 8) * 2 + ImageFileOffset;
    Calculate the pixel value at Xposition, Yposition:
  • Pixelvalue = RawBuffer[RawIndex] * 256 + RawBuffer[RawIndex + 1];
  • 0010/0017 8 digit number:
    27660001 for D7
    27730001 for D5
    0018 0019 Y Size of the CCD:
    0788 = 1928 for D7
    0608 = 1544 for D5
    001A 001B X Size of the CCD:
    0A08 = 2568 for D7
    0808 = 2056 for D5
    001C 001D Y Size of the CCD:
    0788 = 1928 for D7
    0608 = 1544 for D5
    001E 001F X Size of the image:
    0A00 = 2560 for D7
    0800 = 2048 for D5
    002E 002F Unknown yet, vary in each image
    0044 0045 X Size of the image:
    0A00 = 2560 for D7
    0800 = 2048 for D5
    0050 0051 Y Size of the image:
    0780 = 1920 for D7
    0600 = 1536 for D5
    00AA/00B1 0-terminated string "DCF 1.0"
    00B2/00C3 0-terminated string "Minolta Co. Ltd."
    00C4/00CC 0-terminated string "DiMAGE 7" for D7
    0-terminated string "DiMAGE 5" for D5
    00D4/00DB Firmware Version:
    0-terminated string "A1v021e" for D7 for example
    0-terminated string "A2v055u" for D5 for example
    00E4/00F7 Date and Time of the Shot:
    0-terminated string 2001:06:24 12:05:12
    010E 010F ISO:
    0064 = 100
    00C8 = 200
    0190 = 400
    0320 = 800
    01DC 01DD Shutter Time:
    If value > 65000, then substract 65536 from that value.
    Now, the values goes from -20 = 4"0, up to 110 = 1/2000" in 5 step increments.
    -20 = 4"0
    -15 = 3"0
    -10 = 2"0
    -5 = 1"5
    0 = 1"0
    5 = 0"7
    10 = 0"5
    15 = 1/3
    20 = 1/4
    25 = 1/6
    30 = 1/8
    35 = 1/10
    40 = 1/15
    45 = 1/20
    50 = 1/30
    55 = 1/45
    60 = 1/60
    65 = 1/90
    70 = 1/125
    75 = 1/180
    80 = 1/250
    85 = 1/350
    90 = 1/500
    95 = 1/750
    100 = 1/1000
    105 = 1/1500
    110 = 1/2000
    01E5 Aperture:
    The values goes from 30 = 2.8, up to 65 = 9.5 in 5 step increments.
    30 = 2.8
    35 = 3.5
    40 = 4.0
    45 = 4.5
    50 = 5.6
    55 = 6.7
    60 = 8.0
    65 = 9.5
    01FC 01FD Zoom:
    Calculation:
  • (float) Zoom = floor((float)ZoomValue/1.6+0.5)/10.0;
    This is the actual focal length, the value that DIVU returns.
    The lens indicates a different value: the 35 mm film equivalent.
    The 35 mm film (24x36) equivalent has a diagonal of 43.2666153 mm,
    the CCD has a diagonal of 11 mm.
    In order to calculate the 35 mmm equivalent,
    the actual focal length number should be multiplied by 43.2666153 / 11 = 3.93333!
    The two pictures at the bottom of this page show both focal ranges,
    the actual and the 35mm film equivalents.
  • 023C/023F Here is the total file size minus the header size
    FileSize = ContentSize (here) + ImageFileOffset (value at 0006/0007 + 8);
    I don't use this value.
    For calculating the offset of the image data,
    I read locations 0006 and 0007 and increment that value by 8.
    028B Macro:
    00 = No macro
    01 = Macro (Zoom read as 0315)
    02AF Flash:
    00 = No flash
    01 = Flash
    02CA 02CB Picture Number -1 (starts from zero, so need to add 1)
    02D6 02D7 White balance:
    01F1 = AWB
    0164 = Daylight
    028F = Tungsten
    0216 = Fluorescent
    0151 = Cloudy
    0164 = Custom Calibration. (Same as daylight setting)
    02DB Color setting:
    00 = -3
    01 = -2
    02 = -1
    03 = 0
    04 = +1
    05 = +2
    06 = +3
    02DF Contrast setting:
    00 = -3
    01 = -2
    02 = -1
    03 = 0
    04 = +1
    05 = +2
    06 = +3
    02F8 Auto Focus:
    00 = Manual Focus
    AF = Auto Focus (funny value)
    02F8 = 02F9 = 02FA = 02FB (Locations have equal value)
    Note:
    In Manual Focus, the block at locations 0300...03FF is filled with 00's
    In Auto Focus, the block at locations 0300...03FF is filled with data

    Reading Pixel Values

    The data from the D7 RAW file contains a picture of 2568 x 1928 pixels.
    These are two byte integers. The order is MSB first, LSB next.
    The index pointer in the RAW data can be calculated:

  • ImageFileOffset = RawBuffer[0006] * 256 + RawBuffer[0007] + 8;
  • RawIndex = Xposition * 2 + Yposition * (ImageXSize + 8) * 2 + ImageFileOffset;
  • Pixelvalue = RawBuffer[RawIndex] * 256 + RawBuffer[RawIndex + 1];

    Where:

  • at most left, the Xposition = 0
  • at most right, the Xposition = ImageXSize + 8
  • at most top, the Yposition = 0
  • at most bottom, the Yposition = ImageYSize + 8

    The value of the pixel can be extracted:

  • PixelValue = ((char)RawBuffer[RawIndex] & 0xf) * 256 + ((char)RawBuffer[RawIndex+1] & 0xff);
    The pixel values range from 0 to 3965 (0000 to 0F7D). Somehow this value has been clipped at a maximum (white) of 3965 and so does not reach the maximum of the 12 bit value (0FFF = 4095).

    Pixel Color

    You can image having a memory buffer holding the complete raw file. Out of here we calculated the offset where the image data starts. We may like to point into that image data using two "indexing" variables, being the X-position and Y-position.
    The lsb's of those two X and Y variables can be checked in order to determine the pixel color that had been captured at any location.

    For determining the color that was captured at any location, the least significant bits of the values of the X and Y position where the pixel data is being peeked can be tested (see Bayer Pattern more below):

    Getting pixel color from odd/even horizontal and vertical coordinates

    LSB X

    LSB Y

    Pixel Color

    0

    0

    Red

    1

    0

    Green (in horizontal row between Red pixels)

    0

    1

    Green (in horizontal row between Blue pixels)

    1

    1

    Blue

    Bayer Pattern

    The Bayer pattern has a red pixel in the far top-left of the image on the CCD.
    The CCD does measure:

  • 2568 x 1928 pixels for a D7
  • 2056 x 1544 pixels for a D5.

    The figure shows X-Position LSB and Y-Position LSB for 8 x 8 pixels only (as an example), because otherwise it would not fit so well on this page.

     

    0

    1

    0

    1

    0

    1

    0

    1

    0

    R

    G

    R

    G

    R

    G

    R

    G

    1

    G

    B

    G

    B

    G

    B

    G

    B

    0

    R

    G

    R

    G

    R

    G

    R

    G

    1

    G

    B

    G

    B

    G

    B

    G

    B

    0

    R

    G

    R

    G

    R

    G

    R

    G

    1

    G

    B

    G

    B

    G

    B

    G

    B

    0

    R

    G

    R

    G

    R

    G

    R

    G

    1

    G

    B

    G

    B

    G

    B

    G

    B

    The Bayer pattern and coordinate lsb's.

    Web pages for Bayer Pattern interpolation

    The interpolation of a Bayer pattern can be done using several methods. Usually, the better the method, the more processor intensive the algorithm will be. The internal processors of digital cameras should process images as quick as possible. Therefore the used processing may not result in the best possible image quality. A powerful PC can allow for a lot more processing power and time to process an image. This will probably result in an outstanding quality of the processed image.

    Processing can be done in two ways:

  • Non-adaptive
    This is an quick and dirty method, very good for previewing a raw file.
  • Adaptive
    This is an more extensive method, which is slower but takes decisions depending on information from pixels in the neighborhood. There are a number of know algorithms, each with their own advantages. I for myself, preferred the "Variable number of gradients" method which is most slow. I modified it so that more detail was obtained from an image. This was accomplished by a "variable weight" of the measured pixels.
  • On the next web pages, more information can be found:
  • Tingchen - Introduction to Bayer Pattern Interpolation
  • Bayer Pattern processing
  • Tortuga Technologies Pty Ltd. - C-source, Convert a Bayer Pattern CFA to a bitmap
  • The zoom value indicated on the lens is 35mm equivalent

    The zoom value indicated on the lens is the 35mm equivalent.
    The DIVU returns the real value. This value range from 7.2 to 50.8 instead of from 28 to 200.
    This is about a factor of four difference. (sqrt((24^2)+(36^2)) / 11 = 3.93333)
    So be careful interpreting the calculated zoom value!
    In macro you will find approx. 50mm in the EXIF, while the lens indicates 200mm.
    Compare the two pictures below.

     


    The zoom value indicated on the lens ranges from 7.2 to 50.8.
    This is what the DIVU reports too.


    The zoom value indicated on the lens ranges from 28 to 200.
    This is the 35 mm equivalent.