summaryrefslogtreecommitdiffstats
path: root/ext/metadata/metadatamuxjpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/metadata/metadatamuxjpeg.c')
-rw-r--r--ext/metadata/metadatamuxjpeg.c75
1 files changed, 49 insertions, 26 deletions
diff --git a/ext/metadata/metadatamuxjpeg.c b/ext/metadata/metadatamuxjpeg.c
index 15d9d19c..50844a48 100644
--- a/ext/metadata/metadatamuxjpeg.c
+++ b/ext/metadata/metadatamuxjpeg.c
@@ -54,16 +54,49 @@ metadatamux_jpeg_reading (JpegMuxData * jpeg_data, guint8 ** buf,
#define READ(buf, size) ( (size)--, *((buf)++) )
+static void
+metadatamux_wrap_chunk (MetadataChunk * chunk, guint8 * buf, guint32 buf_size,
+ guint8 a, guint8 b)
+{
+ guint8 *data = g_new (guint8, 4 + buf_size + chunk->size);
+
+ memcpy (data + 4 + buf_size, chunk->data, chunk->size);
+ g_free (chunk->data);
+ chunk->data = data;
+ chunk->size += 4 + buf_size;
+ data[0] = a;
+ data[1] = b;
+ data[2] = (chunk->size - 2) >> 8;
+ data[3] = (chunk->size - 2) & 0x00FF;
+ if (buf && buf_size) {
+ memcpy (data + 4, buf, buf_size);
+ }
+}
+
void
metadatamux_jpeg_lazy_update (JpegMuxData * jpeg_data)
{
gsize i;
for (i = 0; i < jpeg_data->inject_chunks->len; ++i) {
- if (jpeg_data->inject_chunks->chunk[i].type == MD_CHUNK_EXIF &&
- jpeg_data->inject_chunks->chunk[i].size > 0) {
- /* zero size chunks should be removed before but we check anyway */
- break;
+ if (jpeg_data->inject_chunks->chunk[i].size > 0 &&
+ jpeg_data->inject_chunks->chunk[i].data) {
+ switch (jpeg_data->inject_chunks->chunk[i].type) {
+ case MD_CHUNK_EXIF:
+ metadatamux_wrap_chunk (&jpeg_data->inject_chunks->chunk[i], NULL, 0,
+ 0xFF, 0xE1);
+ break;
+ case MD_CHUNK_XMP:
+ {
+ static const char XmpHeader[] = "http://ns.adobe.com/xap/1.0/";
+
+ metadatamux_wrap_chunk (&jpeg_data->inject_chunks->chunk[i],
+ XmpHeader, sizeof (XmpHeader), 0xFF, 0xE1);
+ }
+ break;
+ default:
+ break;
+ }
}
}
if (i == jpeg_data->inject_chunks->len) {
@@ -181,21 +214,6 @@ metadatamux_jpeg_reading (JpegMuxData * jpeg_data, guint8 ** buf,
mark[1] = READ (*buf, *bufsize);
if (mark[0] == 0xFF) {
- if (mark[1] == 0xD9) { /* end of image */
- ret = 0;
- jpeg_data->state = JPEG_MUX_DONE;
- goto done;
- } else if (mark[1] == 0xDA) { /* start of scan, lets not look behinf of this */
- ret = 0;
- jpeg_data->state = JPEG_MUX_DONE;
- goto done;
- }
-
- if (*bufsize < 2) {
- *next_size = (*buf - *next_start) + 2;
- ret = 1;
- goto done;
- }
chunk_size = READ (*buf, *bufsize) << 8;
chunk_size += READ (*buf, *bufsize);
@@ -203,27 +221,32 @@ metadatamux_jpeg_reading (JpegMuxData * jpeg_data, guint8 ** buf,
if (mark[1] == 0xE0) { /* may be JFIF */
if (chunk_size >= 16) {
- if (*bufsize < 14) {
- *next_size = (*buf - *next_start) + 14;
+ if (*bufsize < 5) {
+ *next_size = (*buf - *next_start) + 5;
ret = 1;
goto done;
}
if (0 == memcmp (JfifHeader, *buf, 5)) {
jfif_found = TRUE;
- /* FIXME: should we fail if not find JFIF */
- /* Yes, I think so */
}
+ } else {
+ /* FIXME: should we check if the first chunk is EXIF? */
}
}
- new_chunk_offset = (*buf - step_buf) + offset - 4; /* maker + size */
+ if (!jfif_found) {
+ ret = -1;
+ goto done;
+ }
+
+ new_chunk_offset = 2;
/* EXIF will always be in the begining */
memset (&chunk, 0x00, sizeof (MetadataChunk));
- chunk.offset_orig = new_chunk_offset;
+ chunk.offset_orig = 2;
chunk.type = MD_CHUNK_EXIF;
metadata_chunk_array_append_sorted (jpeg_data->inject_chunks, &chunk);
@@ -232,7 +255,7 @@ metadatamux_jpeg_reading (JpegMuxData * jpeg_data, guint8 ** buf,
/* this acation can be canceled with lazy update if no Exif is add */
memset (&chunk, 0x00, sizeof (MetadataChunk));
- chunk.offset_orig = new_chunk_offset;
+ chunk.offset_orig = 2;
chunk.size = chunk_size + 2; /* chunk size plus app marker */
chunk.type = MD_CHUNK_UNKNOWN;