219 lines
6.2 KiB
Diff
219 lines
6.2 KiB
Diff
|
diff -up dcraw/dcraw.c.gps dcraw/dcraw.c
|
||
|
--- dcraw/dcraw.c.gps 2007-12-10 08:43:31.000000000 +0100
|
||
|
+++ dcraw/dcraw.c 2008-01-14 10:05:56.000000000 +0100
|
||
|
@@ -79,6 +79,15 @@ typedef unsigned __int64 UINT64;
|
||
|
typedef long long INT64;
|
||
|
typedef unsigned long long UINT64;
|
||
|
#endif
|
||
|
+#ifdef __GLIBC__
|
||
|
+#define fread(p, s, n, f) fread_unlocked(p, s, n, f)
|
||
|
+#undef putc
|
||
|
+#define putc(c, f) putc_unlocked(c, f)
|
||
|
+#define fputc(c, f) fputc_unlocked(c, f)
|
||
|
+#define fgets(s, n, f) fgets_unlocked(s, n, f)
|
||
|
+#define fwrite(p, s, n, f) fwrite_unlocked(p, s, n, f)
|
||
|
+#define feof(f) feof_unlocked(f)
|
||
|
+#endif
|
||
|
|
||
|
#ifdef LJPEG_DECODE
|
||
|
#error Please compile dcraw.c by itself.
|
||
|
@@ -116,6 +125,13 @@ unsigned tile_width, tile_length;
|
||
|
ushort raw_height, raw_width, height, width, top_margin, left_margin;
|
||
|
ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
|
||
|
int flip, tiff_flip, colors;
|
||
|
+int gpsifdsize;
|
||
|
+struct tiff_tag {
|
||
|
+ ushort tag, type;
|
||
|
+ int count;
|
||
|
+ union { short s0, s1; int i0; } val;
|
||
|
+};
|
||
|
+ushort *gpsifd;
|
||
|
double pixel_aspect, aber[4]={1,1,1,1};
|
||
|
ushort (*image)[4], white[8][8], curve[0x4001], cr2_slice[3], sraw_mul[4];
|
||
|
float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
|
||
|
@@ -4826,6 +4842,119 @@ void CLASS parse_kodak_ifd (int base)
|
||
|
|
||
|
void CLASS parse_minolta (int base);
|
||
|
|
||
|
+void CLASS parse_gps (int base)
|
||
|
+{
|
||
|
+ unsigned entries, tag, type, len, save, datasize, n, m, nonzerotag = 0;
|
||
|
+ unsigned cpoff;
|
||
|
+ ushort *ifd;
|
||
|
+
|
||
|
+ entries = get2();
|
||
|
+ cpoff = 2 + entries * 12 + 4;
|
||
|
+ datasize = cpoff + 100;
|
||
|
+ ifd = malloc(datasize);
|
||
|
+ merror (ifd, "parse_gps()");
|
||
|
+ *ifd = entries;
|
||
|
+ struct tiff_tag *tags = (struct tiff_tag *) (ifd + 1);
|
||
|
+ unsigned *zero = (unsigned*)&tags[entries];
|
||
|
+ *zero = 0;
|
||
|
+ for (n = 0; n < entries; ++n) {
|
||
|
+ tiff_get (base, &tag, &type, &len, &save);
|
||
|
+ tags[n].tag = tag;
|
||
|
+ tags[n].type = type;
|
||
|
+ tags[n].count = len;
|
||
|
+
|
||
|
+ nonzerotag |= tag != 0;
|
||
|
+
|
||
|
+ switch (type)
|
||
|
+ {
|
||
|
+ case 1:
|
||
|
+ case 2:
|
||
|
+ case 6:
|
||
|
+ case 7:
|
||
|
+ if (len <= 4) {
|
||
|
+ tags[n].val.i0 = 0;
|
||
|
+ fread(&tags[n].val, 1, len, ifp);
|
||
|
+ } else {
|
||
|
+ tags[n].val.i0 = cpoff;
|
||
|
+ if (cpoff + len > datasize) {
|
||
|
+ ifd = realloc(ifd, datasize + MAX(100, len));
|
||
|
+ merror (ifd, "parse_gps()");
|
||
|
+ tags = (struct tiff_tag *) (ifd + 1);
|
||
|
+ datasize += MAX(100, len);
|
||
|
+ }
|
||
|
+ fread((char *) ifd + cpoff, len, 1, ifp);
|
||
|
+ cpoff += len;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 3:
|
||
|
+ case 8:
|
||
|
+ if (len <= 2) {
|
||
|
+ tags[n].val.i0 = 0;
|
||
|
+ fread(&tags[n].val, 2, len, ifp);
|
||
|
+ } else {
|
||
|
+ tags[n].val.i0 = cpoff;
|
||
|
+ if (cpoff + 2 * len > datasize) {
|
||
|
+ ifd = realloc(ifd, datasize + MAX(100, 2 * len));
|
||
|
+ merror (ifd, "parse_gps()");
|
||
|
+ tags = (struct tiff_tag *) (ifd + 1);
|
||
|
+ datasize += MAX(100, 2 * len);
|
||
|
+ }
|
||
|
+ for (m = 0; m < len; ++m) {
|
||
|
+ *((ushort *) ((char *) ifd + cpoff)) = get2();
|
||
|
+ cpoff += 2;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 5:
|
||
|
+ case 10:
|
||
|
+ len *= 2;
|
||
|
+ case 4:
|
||
|
+ case 9:
|
||
|
+ case 11:
|
||
|
+ if (len <= 1)
|
||
|
+ fread(&tags[n].val, 4, len, ifp);
|
||
|
+ else {
|
||
|
+ tags[n].val.i0 = cpoff;
|
||
|
+ if (cpoff + 4 * len > datasize) {
|
||
|
+ ifd = realloc(ifd, datasize + MAX(100, 4 * len));
|
||
|
+ merror (ifd, "parse_gps()");
|
||
|
+ tags = (struct tiff_tag *) (ifd + 1);
|
||
|
+ datasize += MAX(100, 4 * len);
|
||
|
+ }
|
||
|
+ for (m = 0; m < len; ++m) {
|
||
|
+ *((unsigned *) ((char *) ifd + cpoff)) = get4();
|
||
|
+ cpoff += 4;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 12:
|
||
|
+ tags[n].val.i0 = cpoff;
|
||
|
+ if (cpoff + 8 * len > datasize) {
|
||
|
+ ifd = realloc(ifd, datasize + MAX(100, 8 * len));
|
||
|
+ merror (ifd, "parse_gps()");
|
||
|
+ tags = (struct tiff_tag *) (ifd + 1);
|
||
|
+ datasize += MAX(100, 8 * len);
|
||
|
+ }
|
||
|
+ for (m = 0; m < len; ++m) {
|
||
|
+ ((unsigned *) ((char *) ifd + cpoff))[1] = get4();
|
||
|
+ ((unsigned *) ((char *) ifd + cpoff))[0] = get4();
|
||
|
+ cpoff += 8;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ fseek (ifp, save, SEEK_SET);
|
||
|
+ }
|
||
|
+ if (nonzerotag) {
|
||
|
+ gpsifdsize = cpoff;
|
||
|
+ gpsifd = ifd;
|
||
|
+ } else
|
||
|
+ free (ifd);
|
||
|
+}
|
||
|
+
|
||
|
int CLASS parse_tiff_ifd (int base)
|
||
|
{
|
||
|
unsigned entries, tag, type, len, plen=16, save;
|
||
|
@@ -5032,6 +5161,10 @@ int CLASS parse_tiff_ifd (int base)
|
||
|
profile_offset = ftell(ifp);
|
||
|
profile_length = len;
|
||
|
break;
|
||
|
+ case 34853: /* GPS IFD */
|
||
|
+ fseek (ifp, get4()+base, SEEK_SET);
|
||
|
+ parse_gps (base);
|
||
|
+ break;
|
||
|
case 37122: /* CompressedBitsPerPixel */
|
||
|
kodak_cbpp = get4();
|
||
|
break;
|
||
|
@@ -7807,17 +7940,11 @@ void CLASS gamma_lut (uchar lut[0x10000]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-struct tiff_tag {
|
||
|
- ushort tag, type;
|
||
|
- int count;
|
||
|
- union { short s0, s1; int i0; } val;
|
||
|
-};
|
||
|
-
|
||
|
struct tiff_hdr {
|
||
|
ushort order, magic;
|
||
|
int ifd;
|
||
|
ushort pad, ntag;
|
||
|
- struct tiff_tag tag[22];
|
||
|
+ struct tiff_tag tag[23];
|
||
|
int nextifd;
|
||
|
ushort pad2, nexif;
|
||
|
struct tiff_tag exif[4];
|
||
|
@@ -7867,7 +7994,7 @@ void CLASS tiff_head (struct tiff_hdr *t
|
||
|
tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model));
|
||
|
if (full) {
|
||
|
if (oprof) psize = ntohl(oprof[0]);
|
||
|
- tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize);
|
||
|
+ tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize + gpsifdsize);
|
||
|
tiff_set (&th->ntag, 277, 3, 1, colors);
|
||
|
tiff_set (&th->ntag, 278, 4, 1, height);
|
||
|
tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8);
|
||
|
@@ -7882,6 +8009,7 @@ void CLASS tiff_head (struct tiff_hdr *t
|
||
|
tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist));
|
||
|
tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif));
|
||
|
if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th);
|
||
|
+ if (full && gpsifdsize) tiff_set (&th->ntag, 34853, 4, 1, sizeof *th + psize);
|
||
|
tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[0]));
|
||
|
tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[2]));
|
||
|
tiff_set (&th->nexif, 34855, 3, 1, iso_speed);
|
||
|
@@ -7942,6 +8070,17 @@ void CLASS write_ppm_tiff (FILE *ofp)
|
||
|
fwrite (&th, sizeof th, 1, ofp);
|
||
|
if (oprof)
|
||
|
fwrite (oprof, ntohl(oprof[0]), 1, ofp);
|
||
|
+ if (gpsifd) {
|
||
|
+ struct tiff_tag *tags = (struct tiff_tag *) (gpsifd + 1);
|
||
|
+ int i;
|
||
|
+ unsigned o = sizeof (th) + (oprof ? ntohl(oprof[0]) : 0);
|
||
|
+ for (i = 0; i < *gpsifd; ++i) {
|
||
|
+ ushort type = tags[i].type;
|
||
|
+ unsigned t = tags[i].count * ("11124811248488"[type < 14 ? type : 0] - '0');
|
||
|
+ if (t > 4) tags[i].val.i0 += o;
|
||
|
+ }
|
||
|
+ fwrite (gpsifd, gpsifdsize, 1, ofp);
|
||
|
+ }
|
||
|
} else if (colors > 3)
|
||
|
fprintf (ofp,
|
||
|
"P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
|