* Reverted parts of r28370:

- the check for compression when counting valid images was wrong, and
    broke all RAW formats that weren't using this compression.
  - COMPRESSION_PACKBITS was defined twice.
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28374 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-10-30 09:29:14 +00:00
parent 1d43a131ea
commit 225c0ed641
2 changed files with 325 additions and 286 deletions
+141 -105
View File
@@ -36,9 +36,6 @@
(fFilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) (fFilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
static const uint32 kImageBufferCount = 10; static const uint32 kImageBufferCount = 10;
static const uint32 kDecodeBufferCount = 2048; static const uint32 kDecodeBufferCount = 2048;
@@ -46,7 +43,7 @@ const double xyz_rgb[3][3] = { /* XYZ from RGB */
{ 0.412453, 0.357580, 0.180423 }, { 0.412453, 0.357580, 0.180423 },
{ 0.212671, 0.715160, 0.072169 }, { 0.212671, 0.715160, 0.072169 },
{ 0.019334, 0.119193, 0.950227 } }; { 0.019334, 0.119193, 0.950227 } };
const float d65_white[3] = { 0.950456, 1, 1.088754 }; const float kD65White[3] = { 0.950456, 1, 1.088754 };
struct decode { struct decode {
struct decode *branch[2]; struct decode *branch[2];
@@ -402,7 +399,8 @@ DCRaw::_ParseManufacturerTag(off_t baseOffset)
uint32 whiteBalance[4] = {0, 0, 0, 0}; uint32 whiteBalance[4] = {0, 0, 0, 0};
off_t offset; off_t offset;
while ((offset = fRead.Position()) < image.data_offset && offset < 16384) { while ((offset = fRead.Position()) < image.data_offset
&& offset < 16384) {
whiteBalance[0] = whiteBalance[2]; whiteBalance[0] = whiteBalance[2];
whiteBalance[2] = whiteBalance[1]; whiteBalance[2] = whiteBalance[1];
whiteBalance[1] = whiteBalance[3]; whiteBalance[1] = whiteBalance[3];
@@ -460,7 +458,8 @@ DCRaw::_ParseManufacturerTag(off_t baseOffset)
off_t nextOffset; off_t nextOffset;
tiff_tag tag; tiff_tag tag;
_ParseTIFFTag(baseOffset, tag, nextOffset); _ParseTIFFTag(baseOffset, tag, nextOffset);
TAG(("Manufacturer tag %u (type %u, length %lu)\n", tag.tag, tag.type, tag.length)); TAG(("Manufacturer tag %u (type %u, length %lu)\n", tag.tag, tag.type,
tag.length));
if (strstr(fMeta.manufacturer, "PENTAX")) { if (strstr(fMeta.manufacturer, "PENTAX")) {
if (tag.tag == 0x1b) if (tag.tag == 0x1b)
@@ -491,7 +490,8 @@ DCRaw::_ParseManufacturerTag(off_t baseOffset)
if (tag.tag == 0x10 && tag.type == 4) if (tag.tag == 0x10 && tag.type == 4)
fUniqueID = fRead.Next<uint32>(); fUniqueID = fRead.Next<uint32>();
if (tag.tag == 0x11) { if (tag.tag == 0x11) {
if (_ParseTIFFImageFileDirectory(baseOffset, fRead.Next<uint32>()) == B_OK) if (_ParseTIFFImageFileDirectory(baseOffset, fRead.Next<uint32>())
== B_OK)
fNumImages++; fNumImages++;
} }
if (tag.tag == 0x14 && tag.length == 2560 && tag.type == 7) { if (tag.tag == 0x14 && tag.length == 2560 && tag.type == 7) {
@@ -517,7 +517,8 @@ DCRaw::_ParseManufacturerTag(off_t baseOffset)
_Thumb().data_offset = fRead.Position(); _Thumb().data_offset = fRead.Position();
_Thumb().bytes = tag.length; _Thumb().bytes = tag.length;
} }
if (tag.tag == 0x88 && tag.type == 4 && (_Thumb().data_offset = fRead.Next<uint32>())) { if (tag.tag == 0x88 && tag.type == 4
&& (_Thumb().data_offset = fRead.Next<uint32>())) {
_Thumb().data_offset += baseOffset; _Thumb().data_offset += baseOffset;
} }
if (tag.tag == 0x89 && tag.type == 4) if (tag.tag == 0x89 && tag.type == 4)
@@ -563,10 +564,12 @@ DCRaw::_ParseManufacturerTag(off_t baseOffset)
buf97[i] ^= (cj += ci * ck++); buf97[i] ^= (cj += ci * ck++);
} }
for (uint32 i = 0; i < 4; i++) { for (uint32 i = 0; i < 4; i++) {
uint16* data = (uint16*)(buf97 + (ver97 == 0x205 ? 14 : 6) + i*2); uint16* data = (uint16*)(buf97
+ (ver97 == 0x205 ? 14 : 6) + i * 2);
if (fRead.IsSwapping()) { if (fRead.IsSwapping()) {
fMeta.camera_multipliers[i ^ (i >> 1)] = __swap_int16(*data); fMeta.camera_multipliers[i ^ (i >> 1)]
= __swap_int16(*data);
} else { } else {
fMeta.camera_multipliers[i ^ (i >> 1)] = *data; fMeta.camera_multipliers[i ^ (i >> 1)] = *data;
} }
@@ -607,8 +610,10 @@ DCRaw::_ParseManufacturerTag(off_t baseOffset)
} }
if (tag.tag == 0xe80 && tag.length == 256 && tag.type == 7) { if (tag.tag == 0xe80 && tag.length == 256 && tag.type == 7) {
fRead.Seek(48, SEEK_CUR); fRead.Seek(48, SEEK_CUR);
fMeta.camera_multipliers[0] = fRead.Next<uint16>() * 508 * 1.078 / 0x10000; fMeta.camera_multipliers[0]
fMeta.camera_multipliers[2] = fRead.Next<uint16>() * 382 * 1.173 / 0x10000; = fRead.Next<uint16>() * 508 * 1.078 / 0x10000;
fMeta.camera_multipliers[2]
= fRead.Next<uint16>() * 382 * 1.173 / 0x10000;
} }
if (tag.tag == 0xf00 && tag.type == 7) { if (tag.tag == 0xf00 && tag.type == 7) {
if (tag.length == 614) if (tag.length == 614)
@@ -659,7 +664,8 @@ get2_256:
if (tag.tag == 0x4001) { if (tag.tag == 0x4001) {
{ {
off_t offset = tag.length == 582 ? 50 : tag.length == 653 ? 68 : 126; off_t offset = tag.length == 582 ? 50 : tag.length == 653
? 68 : 126;
fRead.Seek(offset, SEEK_CUR); fRead.Seek(offset, SEEK_CUR);
} }
get2_rggb: get2_rggb:
@@ -689,7 +695,8 @@ DCRaw::_ParseEXIF(off_t baseOffset)
off_t nextOffset; off_t nextOffset;
tiff_tag tag; tiff_tag tag;
_ParseTIFFTag(baseOffset, tag, nextOffset); _ParseTIFFTag(baseOffset, tag, nextOffset);
TAG(("EXIF tag %u (type %u, length %lu)\n", tag.tag, tag.type, tag.length)); TAG(("EXIF tag %u (type %u, length %lu)\n", tag.tag, tag.type,
tag.length));
switch (tag.tag) { switch (tag.tag) {
#if 0 #if 0
@@ -718,7 +725,8 @@ DCRaw::_ParseEXIF(off_t baseOffset)
break; break;
} }
case 37378: case 37378:
fMeta.aperture = pow(2, fRead.NextDouble(TIFF_FRACTION_TYPE) / 2); fMeta.aperture
= pow(2, fRead.NextDouble(TIFF_FRACTION_TYPE) / 2);
break; break;
case 37386: case 37386:
fMeta.focal_length = fRead.NextDouble(TIFF_FRACTION_TYPE); fMeta.focal_length = fRead.NextDouble(TIFF_FRACTION_TYPE);
@@ -765,8 +773,7 @@ DCRaw::_ParseLinearTable(uint32 length)
} }
/*! /*! This (lengthy) method contains fixes for the values in the image data to
This (lengthy) method contains fixes for the values in the image data to
be able to actually read the image data correctly. be able to actually read the image data correctly.
*/ */
void void
@@ -974,8 +981,10 @@ DCRaw::_ScaleColors()
} }
if (fUserMultipliers[0]) if (fUserMultipliers[0]) {
memcpy(fMeta.pre_multipliers, fUserMultipliers, sizeof(fMeta.pre_multipliers)); memcpy(fMeta.pre_multipliers, fUserMultipliers,
sizeof(fMeta.pre_multipliers));
}
if (fMeta.pre_multipliers[3] == 0) if (fMeta.pre_multipliers[3] == 0)
fMeta.pre_multipliers[3] = fColors < 4 ? fMeta.pre_multipliers[1] : 1; fMeta.pre_multipliers[3] = fColors < 4 ? fMeta.pre_multipliers[1] : 1;
@@ -995,10 +1004,11 @@ DCRaw::_ScaleColors()
dmax = dmin; dmax = dmin;
for (int c = 0; c < 4; c++) { for (int c = 0; c < 4; c++) {
scale_mul[c] = (fMeta.pre_multipliers[c] /= dmax) * 65535.0 / fMeta.maximum; scale_mul[c] = (fMeta.pre_multipliers[c] /= dmax) * 65535.0
/ fMeta.maximum;
} }
#if 1 #if 0
if (1/*verbose*/) { if (1/*verbose*/) {
fprintf(stderr, "Scaling with black %d, multipliers", dblack); fprintf(stderr, "Scaling with black %d, multipliers", dblack);
for (int c = 0; c < 4; c++) { for (int c = 0; c < 4; c++) {
@@ -1077,7 +1087,8 @@ DCRaw::_WaveletDenoise()
} }
temp[-1] = temp[1]; temp[-1] = temp[1];
for (m = 0; m < size; m += 2) { for (m = 0; m < size; m += 2) {
temp[m] += wlet[k+1] * (temp[m-1] + temp[m+1]); temp[m] += wlet[k + 1]
* (temp[m - 1] + temp[m + 1]);
} }
} }
for (m = 0; m < size; m++) { for (m = 0; m < size; m++) {
@@ -1115,7 +1126,8 @@ DCRaw::_WaveletDenoise()
for (k = 3; k > 0; k -= 2) { for (k = 3; k > 0; k -= 2) {
temp[-1] = temp[1]; temp[-1] = temp[1];
for (m = 0; m < size; m += 2) { for (m = 0; m < size; m += 2) {
temp[m] -= wlet[k+1] * (temp[m-1] + temp[m+1]); temp[m] -= wlet[k + 1]
* (temp[m - 1] + temp[m + 1]);
} }
temp[size] = temp[size - 2]; temp[size] = temp[size - 2];
for (m = 1; m < size; m += 2) { for (m = 1; m < size; m += 2) {
@@ -1151,15 +1163,18 @@ DCRaw::_WaveletDenoise()
for (wlast++, i = 0; i < 4; i++) { for (wlast++, i = 0; i < 4; i++) {
window[(i + 3) & 3] = window[i]; window[(i + 3) & 3] = window[i];
} }
for (col = FC(wlast,1) & 1; col < (int32)fInputWidth; col += 2) { for (col = FC(wlast, 1) & 1; col < (int32)fInputWidth;
col += 2) {
window[2][col] = _Bayer(col, wlast); window[2][col] = _Bayer(col, wlast);
} }
} }
for (col = (FC(row, 0) & 1)+1; col < (int32)fInputWidth - 1; col += 2) { for (col = (FC(row, 0) & 1) + 1; col < (int32)fInputWidth - 1;
col += 2) {
avg = ( window[0][col - 1] + window[0][col + 1] avg = ( window[0][col - 1] + window[0][col + 1]
+ window[2][col - 1] + window[2][col + 1] - fMeta.black * 4) + window[2][col - 1] + window[2][col + 1] - fMeta.black * 4)
* mul[row & 1] + (window[1][col] - fMeta.black) * 0.5 + fMeta.black; * mul[row & 1] + (window[1][col] - fMeta.black) * 0.5
+ fMeta.black;
diff = _Bayer(col, row) - avg; diff = _Bayer(col, row) - avg;
if (diff < -fThreshold / M_SQRT2) if (diff < -fThreshold / M_SQRT2)
@@ -1198,7 +1213,8 @@ DCRaw::_PreInterpolate()
for (row = 0; row < fInputHeight; row++) { for (row = 0; row < fInputHeight; row++) {
for (col = 0; col < fInputWidth; col++) { for (col = 0; col < fInputWidth; col++) {
data[row * fInputWidth + col][FC(row, col)] = _Bayer(col, row); data[row * fInputWidth + col][FC(row, col)]
= _Bayer(col, row);
} }
} }
@@ -1237,7 +1253,8 @@ DCRaw::_CameraToCIELab(ushort cam[4], float lab[3])
for (uint32 j = 0; j < fColors; j++) { for (uint32 j = 0; j < fColors; j++) {
xyz_cam[i][j] = 0; xyz_cam[i][j] = 0;
for (uint32 k = 0; k < 3; k++) { for (uint32 k = 0; k < 3; k++) {
xyz_cam[i][j] += xyz_rgb[i][k] * fMeta.rgb_camera[k][j] / d65_white[i]; xyz_cam[i][j] += xyz_rgb[i][k] * fMeta.rgb_camera[k][j]
/ kD65White[i];
} }
} }
} }
@@ -1260,7 +1277,7 @@ DCRaw::_CameraToCIELab(ushort cam[4], float lab[3])
void void
DCRaw::_CameraXYZCoefficients(double cam_xyz[4][3]) DCRaw::_CameraXYZCoefficients(double cameraXYZ[4][3])
{ {
double cam_rgb[4][3], inverse[4][3], num; double cam_rgb[4][3], inverse[4][3], num;
uint32 i, j, k; uint32 i, j, k;
@@ -1269,7 +1286,7 @@ DCRaw::_CameraXYZCoefficients(double cam_xyz[4][3])
for (i = 0; i < fColors; i++) { for (i = 0; i < fColors; i++) {
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
for (cam_rgb[i][j] = k = 0; k < 3; k++) { for (cam_rgb[i][j] = k = 0; k < 3; k++) {
cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j]; cam_rgb[i][j] += cameraXYZ[i][k] * xyz_rgb[k][j];
} }
} }
} }
@@ -1296,8 +1313,7 @@ DCRaw::_CameraXYZCoefficients(double cam_xyz[4][3])
} }
/*! /*! Thanks to Adobe for providing these excellent CAM -> XYZ matrices!
Thanks to Adobe for providing these excellent CAM -> XYZ matrices!
*/ */
void void
DCRaw::_AdobeCoefficients(char *make, char *model) DCRaw::_AdobeCoefficients(char *make, char *model)
@@ -1607,16 +1623,16 @@ DCRaw::_AdobeCoefficients(char *make, char *model)
{ "SONY DSLR-A100", 0, { "SONY DSLR-A100", 0,
{ 9437,-2811,-774,-8405,16215,2290,-710,596,7181 }} { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 }}
}; };
double cam_xyz[4][3]; double cameraXYZ[4][3];
for (uint32 i = 0; i < sizeof table / sizeof *table; i++) { for (uint32 i = 0; i < sizeof table / sizeof *table; i++) {
if (!strncasecmp(model, table[i].prefix, strlen(table[i].prefix))) { if (!strncasecmp(model, table[i].prefix, strlen(table[i].prefix))) {
if (table[i].black) if (table[i].black)
fMeta.black = table[i].black; fMeta.black = table[i].black;
for (uint32 j = 0; j < 12; j++) { for (uint32 j = 0; j < 12; j++) {
cam_xyz[0][j] = table[i].trans[j] / 10000.0; cameraXYZ[0][j] = table[i].trans[j] / 10000.0;
} }
_CameraXYZCoefficients(cam_xyz); _CameraXYZCoefficients(cameraXYZ);
break; break;
} }
} }
@@ -1648,16 +1664,17 @@ DCRaw::_BorderInterpolate(uint32 border)
f = _FilterCoefficient(col, row); f = _FilterCoefficient(col, row);
for (c = 0; c < fColors; c++) { for (c = 0; c < fColors; c++) {
if (c != f && sum[c + 4]) if (c != f && sum[c + 4]) {
fImageData[row * fInputWidth + col][c] = sum[c] / sum[c+4]; fImageData[row * fInputWidth + col][c]
= sum[c] / sum[c + 4];
}
} }
} }
} }
} }
/*! /*! Adaptive Homogeneity-Directed interpolation is based on
Adaptive Homogeneity-Directed interpolation is based on
the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
*/ */
void void
@@ -1699,17 +1716,22 @@ DCRaw::_AHDInterpolate()
memset(rgb, 0, 12 * TS * TS); memset(rgb, 0, 12 * TS * TS);
/* Interpolate green horizontally and vertically: */ /* Interpolate green horizontally and vertically: */
for (row = top < 2 ? 2 : top; row < top + TS && row < fInputHeight - 2; row++) { for (row = top < 2 ? 2 : top; row < top + TS
&& row < fInputHeight - 2; row++) {
col = left + (FC(row, left) == 1); col = left + (FC(row, left) == 1);
if (col < 2) if (col < 2)
col += 2; col += 2;
for (fc = FC(row, col); col < left + TS && col < fInputWidth - 2; col += 2) { for (fc = FC(row, col); col < left + TS
&& col < fInputWidth - 2; col += 2) {
pix = fImageData + row * fInputWidth + col; pix = fImageData + row * fInputWidth + col;
val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2 val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2
- pix[-2][fc] - pix[2][fc]) >> 2; - pix[-2][fc] - pix[2][fc]) >> 2;
rgb[0][row - top][col - left][1] = ULIM(val, pix[-1][1], pix[1][1]); rgb[0][row - top][col - left][1]
val = ((pix[-fInputWidth][1] + pix[0][fc] + pix[fInputWidth][1]) * 2 = ULIM(val, pix[-1][1], pix[1][1]);
- pix[-2 * fInputWidth][fc] - pix[2 * fInputWidth][fc]) >> 2; val = ((pix[-fInputWidth][1] + pix[0][fc]
+ pix[fInputWidth][1]) * 2
- pix[-2 * fInputWidth][fc] - pix[2 * fInputWidth][fc])
>> 2;
rgb[1][row - top][col - left][1] = ULIM(val, rgb[1][row - top][col - left][1] = ULIM(val,
pix[-fInputWidth][1], pix[fInputWidth][1]); pix[-fInputWidth][1], pix[fInputWidth][1]);
} }
@@ -1717,8 +1739,10 @@ DCRaw::_AHDInterpolate()
/* Interpolate red and blue, and convert to CIELab: */ /* Interpolate red and blue, and convert to CIELab: */
for (d = 0; d < 2; d++) { for (d = 0; d < 2; d++) {
for (row = top + 1; row < top + TS - 1 && row < fInputHeight - 1; row++) { for (row = top + 1; row < top + TS - 1
for (col = left + 1; col < left + TS - 1 && col < fInputWidth - 1; col++) { && row < fInputHeight - 1; row++) {
for (col = left + 1; col < left + TS - 1
&& col < fInputWidth - 1; col++) {
pix = fImageData + row * fInputWidth + col; pix = fImageData + row * fInputWidth + col;
rix = &rgb[d][row - top][col - left]; rix = &rgb[d][row - top][col - left];
if ((c = 2 - FC(row, col)) == 1) { if ((c = 2 - FC(row, col)) == 1) {
@@ -1732,7 +1756,8 @@ DCRaw::_AHDInterpolate()
} else { } else {
val = rix[0][1] + ((pix[-fInputWidth - 1][c] val = rix[0][1] + ((pix[-fInputWidth - 1][c]
+ pix[-fInputWidth + 1][c] + pix[-fInputWidth + 1][c]
+ pix[fInputWidth - 1][c] + pix[fInputWidth + 1][c] + pix[fInputWidth - 1][c]
+ pix[fInputWidth + 1][c]
- rix[-TS - 1][1] - rix[-TS + 1][1] - rix[-TS - 1][1] - rix[-TS + 1][1]
- rix[TS - 1][1] - rix[TS + 1][1] + 1) >> 2); - rix[TS - 1][1] - rix[TS + 1][1] + 1) >> 2);
} }
@@ -1741,7 +1766,8 @@ DCRaw::_AHDInterpolate()
rix[0][c] = pix[0][c]; rix[0][c] = pix[0][c];
_CameraToCIELab(rix[0], flab); _CameraToCIELab(rix[0], flab);
for (c = 0; c < 3; c++) { for (c = 0; c < 3; c++) {
lab[d][row - top][col - left][c] = int16(64 * flab[c]); lab[d][row - top][col - left][c]
= int16(64 * flab[c]);
} }
} }
} }
@@ -1751,11 +1777,13 @@ DCRaw::_AHDInterpolate()
memset(homo, 0, 2 * TS * TS); memset(homo, 0, 2 * TS * TS);
for (row = top + 2; row < top+TS-2 && row < fInputHeight; row++) { for (row = top + 2; row < top+TS-2 && row < fInputHeight; row++) {
tr = row - top; tr = row - top;
for (col = left + 2; col < left + TS - 2 && col < fInputWidth; col++) { for (col = left + 2; col < left + TS - 2
&& col < fInputWidth; col++) {
tc = col - left; tc = col - left;
for (d = 0; d < 2; d++) { for (d = 0; d < 2; d++) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
ldiff[d][i] = ABS(lab[d][tr][tc][0]-lab[d][tr][tc+dir[i]][0]); ldiff[d][i] = ABS(lab[d][tr][tc][0]
- lab[d][tr][tc+dir[i]][0]);
} }
} }
@@ -1765,8 +1793,10 @@ DCRaw::_AHDInterpolate()
for (d = 0; d < 2; d++) { for (d = 0; d < 2; d++) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (i >> 1 == d || ldiff[d][i] <= leps) { if (i >> 1 == d || ldiff[d][i] <= leps) {
abdiff[d][i] = square(lab[d][tr][tc][1]-lab[d][tr][tc+dir[i]][1]) abdiff[d][i] = square(lab[d][tr][tc][1]
+ square(lab[d][tr][tc][2]-lab[d][tr][tc+dir[i]][2]); - lab[d][tr][tc+dir[i]][1])
+ square(lab[d][tr][tc][2]
- lab[d][tr][tc+dir[i]][2]);
} }
} }
} }
@@ -1784,9 +1814,11 @@ DCRaw::_AHDInterpolate()
} }
/* Combine the most homogenous pixels for the final result: */ /* Combine the most homogenous pixels for the final result: */
for (row = top + 3; row < top + TS - 3 && row < fInputHeight - 3; row++) { for (row = top + 3; row < top + TS - 3 && row < fInputHeight - 3;
row++) {
tr = row - top; tr = row - top;
for (col = left + 3; col < left + TS - 3 && col < fInputWidth - 3; col++) { for (col = left + 3; col < left + TS - 3
&& col < fInputWidth - 3; col++) {
tc = col - left; tc = col - left;
for (d = 0; d < 2; d++) { for (d = 0; d < 2; d++) {
for (hm[d] = 0, i = tr - 1; i <= tr + 1; i++) { for (hm[d] = 0, i = tr - 1; i <= tr + 1; i++) {
@@ -1868,33 +1900,33 @@ DCRaw::_ConvertToRGB()
uint32 row, col, c, i, j, k; uint32 row, col, c, i, j, k;
float out[3], out_cam[3][4]; float out[3], out_cam[3][4];
double num, inverse[3][3]; double num, inverse[3][3];
static const double xyzd50_srgb[3][3] = static const double xyzd50_srgb[3][3] = {
{ { 0.436083, 0.385083, 0.143055 }, { 0.436083, 0.385083, 0.143055 },
{ 0.222507, 0.716888, 0.060608 }, { 0.222507, 0.716888, 0.060608 },
{ 0.013930, 0.097097, 0.714022 }}; { 0.013930, 0.097097, 0.714022 }};
static const double rgb_rgb[3][3] = static const double rgb_rgb[3][3] = {
{ { 1,0,0 }, { 0,1,0 }, { 0,0,1 } }; { 1,0,0 }, { 0,1,0 }, { 0,0,1 }};
static const double adobe_rgb[3][3] = static const double adobe_rgb[3][3] = {
{ { 0.715146, 0.284856, 0.000000 }, { 0.715146, 0.284856, 0.000000 },
{ 0.000000, 1.000000, 0.000000 }, { 0.000000, 1.000000, 0.000000 },
{ 0.000000, 0.041166, 0.958839 }}; { 0.000000, 0.041166, 0.958839 }};
static const double wide_rgb[3][3] = static const double wide_rgb[3][3] = {
{ { 0.593087, 0.404710, 0.002206 }, { 0.593087, 0.404710, 0.002206 },
{ 0.095413, 0.843149, 0.061439 }, { 0.095413, 0.843149, 0.061439 },
{ 0.011621, 0.069091, 0.919288 }}; { 0.011621, 0.069091, 0.919288 }};
static const double prophoto_rgb[3][3] = static const double prophoto_rgb[3][3] = {
{ { 0.529317, 0.330092, 0.140588 }, { 0.529317, 0.330092, 0.140588 },
{ 0.098368, 0.873465, 0.028169 }, { 0.098368, 0.873465, 0.028169 },
{ 0.016879, 0.117663, 0.865457 }}; { 0.016879, 0.117663, 0.865457 }};
static const double (*out_rgb[])[3] = static const double (*out_rgb[])[3]
{ rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; = { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb };
static const char *name[] = static const char *name[] = { "sRGB", "Adobe RGB (1998)", "WideGamut D65",
{ "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; "ProPhoto D65", "XYZ" };
static const unsigned phead[] = static const unsigned phead[] = { 1024, 0, 0x2100000, 0x6d6e7472,
{ 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, 0x52474220, 0x58595a20, 0, 0, 0, 0x61637370, 0, 0, 0x6e6f6e65,
0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d };
unsigned pbody[] = unsigned pbody[] = { 10,
{ 10, 0x63707274, 0, 36, /* cprt */ 0x63707274, 0, 36, /* cprt */
0x64657363, 0, 40, /* desc */ 0x64657363, 0, 40, /* desc */
0x77747074, 0, 20, /* wtpt */ 0x77747074, 0, 20, /* wtpt */
0x626b7074, 0, 20, /* bkpt */ 0x626b7074, 0, 20, /* bkpt */
@@ -1921,7 +1953,8 @@ DCRaw::_ConvertToRGB()
fOutputProfile[0] = 132 + 12 * pbody[0]; fOutputProfile[0] = 132 + 12 * pbody[0];
for (i = 0; i < pbody[0]; i++) { for (i = 0; i < pbody[0]; i++) {
fOutputProfile[fOutputProfile[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; fOutputProfile[fOutputProfile[0] / 4]
= i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874;
pbody[i*3+2] = fOutputProfile[0]; pbody[i*3+2] = fOutputProfile[0];
fOutputProfile[0] += (pbody[i*3+3] + 3) & -4; fOutputProfile[0] += (pbody[i*3+3] + 3) & -4;
} }
@@ -1938,7 +1971,8 @@ DCRaw::_ConvertToRGB()
} }
for (i = 4; i < 7; i++) { for (i = 4; i < 7; i++) {
memcpy((char *)fOutputProfile + pbody[i*3+2], pcurve, sizeof(pcurve)); memcpy((char *)fOutputProfile + pbody[i * 3 + 2], pcurve,
sizeof(pcurve));
} }
_PseudoInverse((double (*)[3])out_rgb[fOutputColor - 1], inverse, 3); _PseudoInverse((double (*)[3])out_rgb[fOutputColor - 1], inverse, 3);
@@ -1948,19 +1982,22 @@ DCRaw::_ConvertToRGB()
for (num = k=0; k < 3; k++) { for (num = k=0; k < 3; k++) {
num += xyzd50_srgb[i][k] * inverse[j][k]; num += xyzd50_srgb[i][k] * inverse[j][k];
} }
fOutputProfile[pbody[j * 3 + 23] / 4 + i + 2] = uint32(num * 0x10000 + 0.5); fOutputProfile[pbody[j * 3 + 23] / 4 + i + 2]
= uint32(num * 0x10000 + 0.5);
} }
} }
for (i = 0; i < phead[0]/4; i++) { for (i = 0; i < phead[0]/4; i++) {
fOutputProfile[i] = htonl(fOutputProfile[i]); fOutputProfile[i] = htonl(fOutputProfile[i]);
} }
strcpy((char *)fOutputProfile + pbody[2] + 8, "auto-generated by dcraw"); strcpy((char *)fOutputProfile + pbody[2] + 8,
"auto-generated by dcraw");
strcpy((char *)fOutputProfile + pbody[5] + 12, name[fOutputColor - 1]); strcpy((char *)fOutputProfile + pbody[5] + 12, name[fOutputColor - 1]);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
for (j = 0; j < fColors; j++) { for (j = 0; j < fColors; j++) {
for (out_cam[i][j] = k = 0; k < 3; k++) { for (out_cam[i][j] = k = 0; k < 3; k++) {
out_cam[i][j] += out_rgb[fOutputColor-1][i][k] * fMeta.rgb_camera[k][j]; out_cam[i][j] += out_rgb[fOutputColor-1][i][k]
* fMeta.rgb_camera[k][j];
} }
} }
} }
@@ -2052,8 +2089,7 @@ DCRaw::_InitDecoder()
} }
/*! /*! Construct a decode tree according the specification in *source.
Construct a decode tree according the specification in *source.
The first 16 bytes specify how many codes should be 1-bit, 2-bit The first 16 bytes specify how many codes should be 1-bit, 2-bit
3-bit, etc. Bytes after that are the leaf values. 3-bit, etc. Bytes after that are the leaf values.
@@ -2084,7 +2120,8 @@ DCRaw::_MakeDecoder(const uchar* source, int level)
if (level == 0) if (level == 0)
fDecodeLeaf = 0; fDecodeLeaf = 0;
if ((uint8*)fFreeDecode > (uint8*)fDecodeBuffer + sizeof(decode) * kDecodeBufferCount) { if ((uint8*)fFreeDecode > (uint8*)fDecodeBuffer
+ sizeof(decode) * kDecodeBufferCount) {
fprintf(stderr, "decoder table overflow\n"); fprintf(stderr, "decoder table overflow\n");
throw (status_t)B_ERROR; throw (status_t)B_ERROR;
} }
@@ -2110,12 +2147,9 @@ DCRaw::_MakeDecoder(const uchar* source, int level)
} }
/* /*! Not a full implementation of Lossless JPEG, just
Not a full implementation of Lossless JPEG, just
enough to decode Canon, Kodak and Adobe DNG images. enough to decode Canon, Kodak and Adobe DNG images.
*/ */
void void
DCRaw::_InitDecodeBits() DCRaw::_InitDecodeBits()
{ {
@@ -2124,8 +2158,7 @@ DCRaw::_InitDecodeBits()
} }
/*! /*! _GetDecodeBits(n) where 0 <= n <= 25 returns an n-bit integer
_GetDecodeBits(n) where 0 <= n <= 25 returns an n-bit integer
*/ */
uint32 uint32
DCRaw::_GetDecodeBits(uint32 numBits) DCRaw::_GetDecodeBits(uint32 numBits)
@@ -2135,7 +2168,8 @@ DCRaw::_GetDecodeBits(uint32 numBits)
while (fDecodeBitsRead < numBits) { while (fDecodeBitsRead < numBits) {
uint8 c = fRead.Next<uint8>(); uint8 c = fRead.Next<uint8>();
if ((fDecodeBitsReset = fDecodeBitsZeroAfterMax && c == 0xff && fRead.Next<uint8>())) if ((fDecodeBitsReset = fDecodeBitsZeroAfterMax
&& c == 0xff && fRead.Next<uint8>()))
return 0; return 0;
fDecodeBits = (fDecodeBits << 8) + c; fDecodeBits = (fDecodeBits << 8) + c;
fDecodeBitsRead += 8; fDecodeBitsRead += 8;
@@ -2259,8 +2293,7 @@ DCRaw::_LosslessJPEGRow(struct jhead *jh, int jrow)
// #pragma mark - RAW loaders // #pragma mark - RAW loaders
/*! /*! This is, for example, used in PENTAX RAW images
This is, for example, used in PENTAX RAW images
*/ */
void void
DCRaw::_LoadRAWPacked12(const image_data_info& image) DCRaw::_LoadRAWPacked12(const image_data_info& image)
@@ -2353,8 +2386,7 @@ DCRaw::_MakeCanonDecoder(uint32 table)
} }
/*! /*! Return 0 if the image starts with compressed data,
Return 0 if the image starts with compressed data,
1 if it starts with uncompressed low-order bits. 1 if it starts with uncompressed low-order bits.
In Canon compressed data, 0xff is always followed by 0x00. In Canon compressed data, 0xff is always followed by 0x00.
@@ -2557,7 +2589,8 @@ DCRaw::_LoadRAW(const image_data_info& image)
break; break;
default: default:
fprintf(stderr, "DCRaw: unknown compression: %ld\n", image.compression); fprintf(stderr, "DCRaw: unknown compression: %ld\n",
image.compression);
throw (status_t)B_NO_TRANSLATOR; throw (status_t)B_NO_TRANSLATOR;
break; break;
} }
@@ -2688,8 +2721,7 @@ DCRaw::_ParseTIFFTimestamp(bool reversed)
} }
/*! /*! Reads a TIFF tag and positions the file stream to its data section
Reads a TIFF tag and positions the file stream to its data section
*/ */
void void
DCRaw::_ParseTIFFTag(off_t baseOffset, tiff_tag& tag, off_t& offset) DCRaw::_ParseTIFFTag(off_t baseOffset, tiff_tag& tag, off_t& offset)
@@ -2739,7 +2771,7 @@ DCRaw::_ParseTIFFImageFileDirectory(off_t baseOffset, uint32 offset)
double analogBalance[] = {1, 1, 1, 1}; double analogBalance[] = {1, 1, 1, 1};
double xyz[] = {1, 1, 1, 1}; double xyz[] = {1, 1, 1, 1};
bool useColorMatrix = false; bool useColorMatrix = false;
double cameraCalibration[4][4], colorMatrix[4][3], cam_xyz[4][3]; double cameraCalibration[4][4], colorMatrix[4][3], cameraXYZ[4][3];
for (int32 j = 0; j < 4; j++) { for (int32 j = 0; j < 4; j++) {
for (int32 i = 0; i < 4; i++) { for (int32 i = 0; i < 4; i++) {
@@ -2771,8 +2803,10 @@ DCRaw::_ParseTIFFImageFileDirectory(off_t baseOffset, uint32 offset)
case 17: case 17:
case 18: case 18:
if (tag.type == 3 && tag.length == 1) if (tag.type == 3 && tag.length == 1) {
fMeta.camera_multipliers[(tag.tag - 17) * 2] = fRead.Next<uint16>() / 256.0; fMeta.camera_multipliers[(tag.tag - 17) * 2]
= fRead.Next<uint16>() / 256.0;
}
break; break;
case 23: // ISO speed case 23: // ISO speed
@@ -3143,7 +3177,7 @@ DCRaw::_ParseTIFFImageFileDirectory(off_t baseOffset, uint32 offset)
xyz[0] = getrat(); xyz[0] = getrat();
xyz[1] = getrat(); xyz[1] = getrat();
xyz[2] = 1 - xyz[0] - xyz[1]; xyz[2] = 1 - xyz[0] - xyz[1];
FORC3 xyz[c] /= d65_white[c]; FORC3 xyz[c] /= kD65White[c];
break; break;
case 50740: /* DNGPrivateData */ case 50740: /* DNGPrivateData */
if (dng_version) break; if (dng_version) break;
@@ -3204,14 +3238,14 @@ DCRaw::_ParseTIFFImageFileDirectory(off_t baseOffset, uint32 offset)
if (useColorMatrix) { if (useColorMatrix) {
for (uint32 c = 0; c < fColors; c++) { for (uint32 c = 0; c < fColors; c++) {
for (uint32 i = 0; i < 3; i++) { for (uint32 i = 0; i < 3; i++) {
cam_xyz[c][i] = 0; cameraXYZ[c][i] = 0;
for (uint32 j = 0; j < fColors; j++) { for (uint32 j = 0; j < fColors; j++) {
cam_xyz[c][i] += cameraCalibration[c][j] cameraXYZ[c][i] += cameraCalibration[c][j]
* colorMatrix[j][i] * xyz[i]; * colorMatrix[j][i] * xyz[i];
} }
} }
} }
_CameraXYZCoefficients(cam_xyz); _CameraXYZCoefficients(cameraXYZ);
} }
#if 0 #if 0
@@ -3302,7 +3336,8 @@ DCRaw::_ParseTIFF(off_t baseOffset)
} }
} }
if (fRawIndex < 0 || (!fDNGVersion && _Raw().samples == 3 && _Raw().bits_per_sample == 8)) if (fRawIndex < 0
|| (!fDNGVersion && _Raw().samples == 3 && _Raw().bits_per_sample == 8))
throw (status_t)B_NO_TRANSLATOR; throw (status_t)B_NO_TRANSLATOR;
if (fRawIndex >= 0) { if (fRawIndex >= 0) {
@@ -3417,7 +3452,8 @@ DCRaw::Identify()
int32 rawCount = 0; int32 rawCount = 0;
for (int32 i = 0; i < (int32)fNumImages; i++) { for (int32 i = 0; i < (int32)fNumImages; i++) {
if (fImages[i].width == 0 || fImages[i].height == 0 || fImages[i].data_offset == 0) { if (fImages[i].width == 0 || fImages[i].height == 0
|| fImages[i].data_offset == 0) {
fNumImages--; fNumImages--;
if (i == fRawIndex) if (i == fRawIndex)
fRawIndex = -1; fRawIndex = -1;
@@ -3433,7 +3469,7 @@ DCRaw::Identify()
sizeof(image_data_info) * (fNumImages - i)); sizeof(image_data_info) * (fNumImages - i));
} }
i--; i--;
} else if (fImages[i].is_raw && fImages[i].compression == COMPRESSION_PACKBITS) } else if (fImages[i].is_raw)
rawCount++; rawCount++;
} }
+5 -2
View File
@@ -8,11 +8,10 @@
#include "ReadHelper.h" #include "ReadHelper.h"
struct jhead; struct jhead;
struct tiff_tag; struct tiff_tag;
#define COMPRESSION_PACKBITS 32773
struct image_meta_info { struct image_meta_info {
char manufacturer[64]; char manufacturer[64];
@@ -52,6 +51,10 @@ struct image_data_info {
bool is_raw; bool is_raw;
}; };
#define COMPRESSION_PACKBITS 32773
/* Macintosh RLE */
typedef void (*monitor_hook)(const char* message, float percentage, void* data); typedef void (*monitor_hook)(const char* message, float percentage, void* data);
class DCRaw { class DCRaw {