#define DEBUG 1
#define OLD 1
void CLASS sony_arw2_load_raw()
{
uchar *data, *dp; // pointers into compressed raw data line buffer
ushort pdata; // uncompressed raw value (11 bits used, expandable up to 15 bits
int row, col, val, max, min, imax, imin, sh, bit, i; // these are signed 32-bit variables
data = (uchar *) malloc(raw_width); // allocate memory for one raw data line
merror (data, "sony_arw2_load_raw()"); // bail out on allocation errors
for (row=0; row < height; row++) { // run through lines of compressed raw data
fread(data, 1, raw_width, ifp); // read compressed raw data into line buffer
for (dp=data, col=0; col < raw_width-30; dp+=16) { // run through columns in line buffer,
// process 16 bytes (128 bits) in one go
// evaluate header of compressed cluster of pixel data by getting 32 bit value from buffer
max = 0x7FF & (val = sget4(dp)); // max is bits 10..0 (11 bits for 0..2047)
min = 0x7FF & val >> 11; // min is bits 21..11 (11 bits for 0..2047)
imax = 0x0F & val >> 22; // imax is bits 25..22 (4 bits for 0..15)
imin = 0x0F & val >> 26; // imin is bits 29..26 (4 bits for 0..15)
#if DEBUG
if (imax == imin) // must not occur as we cannot correctly decode it. May indicate "hidden data".
fprintf(stderr, _("DEBUG: Unknown ARW data header format near 0x%llx.\n"), dp);
if (max == min) // may theoretically occur in data, but is unusual and may indicate "hidden data".
fprintf(stderr, _("DEBUG: Unusual data in ARW data header near 0x%llx: Window size zero.\n"), dp);
else if (max < min) // must not occur, as we cannot correctly decode it. May indicate "hidden data".
fprintf(stderr, _("DEBUG: Unusual data in ARW data header near 0x%llx: Negative window size.\n"), dp);
else if (max-min < 64) // may occur in data, but is unusual as smallest window size for 7-bit data is 128. May indicate "hidden data".
fprintf(stderr, _("DEBUG: Unusual data in ARW data header near 0x%llx: Tiny window size.\n"), dp);
#endif
// bits 31 and 30 remain unused for header, but will be used for pixel data further below
// max and min define highest and lowest margins in compressed cluster of 16 pixel data values.
// 11 bits allow values of 0..2047 at most
// imax and imin define which 2 data values in compressed cluster correspond with margin values
// 4 bits are sufficient as an index into 16 pixel data values contained in cluster
// determine bit width of window of values (max-min) in compressed pixel data cluster
for (sh=0; 0x80 << sh <= max-min; sh++);
// sh is 0 for window of 128, 1 for 256, 2 for 512, 3 for 1024, 4 for 2048 possible values
// values > 4 cannot occur with max/min being 11-bit values, but may be supported in the future
// decompress 16 pixel data values from following 128-30 bit cluster in line buffer
for (bit=30, i=0; i < 16; i++, col+=2, bit += 7) { // start at bit 30 in 128 bit cluster
if (i == imax) // is highest value in cluster?
pdata = max; // not stored inline, take from header as 11-bit
else
if (i == imin) // is lowest value in cluster?
pdata = min; // not stored inline, take from header as 11-bit
else { // remaining 14 data values are stored inline as 7-bit values
pdata = ((sget2(dp+(bit >> 3)) // get sliding window of 16 bits from line buffer
>> (bit & 7) // zero-align currently relevant 7 bits
& 0x7F) // strip off other bits, lowest 7 bits make up value now
<< sh) // blow up in proportion to window size
// (times 1 for 7, 2 for 8, 4 for 9, 8 for 10, 16 for 11 bits)
+ min; // offset to low margin of window
#if DEBUG
if (pdata > max) // may theoretically occur in data, but is unusual and may indicate "hidden data".
fprintf(stderr, _("DEBUG: ARW data decompression resulted in data outside window near 0x%llx: .\n"), dp);
if (pdata > 0x7FF) // Unusual condition, but not necessarily invalid, therefore no reason to clip
fprintf(stderr, _("DEBUG: ARW data decompression resulted in 12-bit rather than 11-bit value near 0x%llx.\n"), dp);
#endif
#if OLD // let's keep it this way for now for compatibility with existing code
RAW(row, col) = curve[pdata << 1] >> 2; // apply camera curve and store in raw picture buffer
#else
RAW(row, col) = curve[pdata]; // apply camera curve and store in raw picture buffer
#endif
// store resulting raw value away as 2 bytes in raw picture buffer
// (RAW macro addresses bytes in buffer, hence we must increment col by 2)
}
col -= (col & 1) ? 1:31; // substract 1 if column odd, 31 if even
}
}
free(data); // free previously allocated memory
}