summaryrefslogtreecommitdiff
path: root/src/libexif/exif-loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexif/exif-loader.c')
-rw-r--r--src/libexif/exif-loader.c106
1 files changed, 84 insertions, 22 deletions
diff --git a/src/libexif/exif-loader.c b/src/libexif/exif-loader.c
index d6eba7d..4e5b140 100644
--- a/src/libexif/exif-loader.c
+++ b/src/libexif/exif-loader.c
@@ -1,18 +1,46 @@
+/* exif-loader.c
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
#include <config.h>
#include <libexif/exif-loader.h>
+#include <libexif/exif-utils.h>
#include <libexif/i18n.h>
+#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#undef JPEG_MARKER_DHT
+#define JPEG_MARKER_DHT 0xc4
#undef JPEG_MARKER_SOI
#define JPEG_MARKER_SOI 0xd8
+#undef JPEG_MARKER_DQT
+#define JPEG_MARKER_DQT 0xdb
#undef JPEG_MARKER_APP0
#define JPEG_MARKER_APP0 0xe0
#undef JPEG_MARKER_APP1
#define JPEG_MARKER_APP1 0xe1
+#undef JPEG_MARKER_APP2
+#define JPEG_MARKER_APP2 0xe2
#undef JPEG_MARKER_APP13
#define JPEG_MARKER_APP13 0xed
#undef JPEG_MARKER_COM
@@ -60,10 +88,12 @@ exif_loader_alloc (ExifLoader *l, unsigned int i)
{
void *d;
- if (!l || !i) return NULL;
+ if (!l || !i)
+ return NULL;
d = exif_mem_alloc (l->mem, i);
- if (d) return d;
+ if (d)
+ return d;
EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i);
return NULL;
@@ -79,7 +109,8 @@ exif_loader_write_file (ExifLoader *l, const char *path)
int size;
unsigned char data[1024];
- if (!l) return;
+ if (!l)
+ return;
f = fopen (path, "rb");
if (!f) {
@@ -89,8 +120,10 @@ exif_loader_write_file (ExifLoader *l, const char *path)
}
while (1) {
size = fread (data, 1, sizeof (data), f);
- if (size <= 0) break;
- if (!exif_loader_write (l, data, size)) break;
+ if (size <= 0)
+ break;
+ if (!exif_loader_write (l, data, size))
+ break;
}
fclose (f);
}
@@ -98,11 +131,14 @@ exif_loader_write_file (ExifLoader *l, const char *path)
static unsigned int
exif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len)
{
- if (!eld || (len && !buf) || (eld->bytes_read >= eld->size)) return 0;
+ if (!eld || (len && !buf) || (eld->bytes_read >= eld->size))
+ return 0;
/* If needed, allocate the buffer. */
- if (!eld->buf) eld->buf = exif_loader_alloc (eld, eld->size);
- if (!eld->buf) return 0;
+ if (!eld->buf)
+ eld->buf = exif_loader_alloc (eld, eld->size);
+ if (!eld->buf)
+ return 0;
/* Copy memory */
len = MIN (len, eld->size - eld->bytes_read);
@@ -117,13 +153,17 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
{
unsigned int i;
- if (!eld || (len && !buf)) return 0;
+ if (!eld || (len && !buf))
+ return 0;
switch (eld->state) {
case EL_EXIF_FOUND:
return exif_loader_copy (eld, buf, len);
case EL_SKIP_BYTES:
- if (eld->size > len) { eld->size -= len; return 1; }
+ if (eld->size > len) {
+ eld->size -= len;
+ return 1;
+ }
len -= eld->size;
buf += eld->size;
eld->size = 0;
@@ -141,6 +181,8 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
break;
}
+ if (!len)
+ return 1;
exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
"Scanning %i byte(s) of data...", len);
@@ -152,7 +194,8 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
if (i) {
memcpy (&eld->b[eld->b_len], buf, i);
eld->b_len += i;
- if (eld->b_len < sizeof (eld->b)) return 1;
+ if (eld->b_len < sizeof (eld->b))
+ return 1;
buf += i;
len -= i;
}
@@ -183,11 +226,13 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
switch (eld->state) {
case EL_EXIF_FOUND:
if (!exif_loader_copy (eld, eld->b + i,
- sizeof (eld->b) - i)) return 0;
+ sizeof (eld->b) - i))
+ return 0;
return exif_loader_copy (eld, buf, len);
case EL_SKIP_BYTES:
eld->size--;
- if (!eld->size) eld->state = EL_READ;
+ if (!eld->size)
+ eld->state = EL_READ;
break;
case EL_READ_SIZE_BYTE_24:
@@ -225,11 +270,18 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
default:
switch (eld->b[i]) {
case JPEG_MARKER_APP1:
- eld->data_format = EL_DATA_FORMAT_EXIF;
+ if (!memcmp (eld->b + i + 3, ExifHeader, MIN((ssize_t)(sizeof(ExifHeader)), MAX(0, ((ssize_t)(sizeof(eld->b))) - ((ssize_t)i) - 3)))) {
+ eld->data_format = EL_DATA_FORMAT_EXIF;
+ } else {
+ eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/
+ }
eld->size = 0;
eld->state = EL_READ_SIZE_BYTE_08;
break;
+ case JPEG_MARKER_DHT:
+ case JPEG_MARKER_DQT:
case JPEG_MARKER_APP0:
+ case JPEG_MARKER_APP2:
case JPEG_MARKER_APP13:
case JPEG_MARKER_COM:
eld->data_format = EL_DATA_FORMAT_JPEG;
@@ -274,10 +326,12 @@ exif_loader_new_mem (ExifMem *mem)
{
ExifLoader *loader;
- if (!mem) return NULL;
+ if (!mem)
+ return NULL;
loader = exif_mem_alloc (mem, sizeof (ExifLoader));
- if (!loader) return NULL;
+ if (!loader)
+ return NULL;
loader->ref_count = 1;
loader->mem = mem;
@@ -289,7 +343,8 @@ exif_loader_new_mem (ExifMem *mem)
void
exif_loader_ref (ExifLoader *loader)
{
- if (loader) loader->ref_count++;
+ if (loader)
+ loader->ref_count++;
}
static void
@@ -297,10 +352,12 @@ exif_loader_free (ExifLoader *loader)
{
ExifMem *mem;
- if (!loader) return;
+ if (!loader)
+ return;
mem = loader->mem;
exif_loader_reset (loader);
+ exif_log_unref (loader->log);
exif_mem_free (mem, loader);
exif_mem_unref (mem);
}
@@ -308,7 +365,8 @@ exif_loader_free (ExifLoader *loader)
void
exif_loader_unref (ExifLoader *loader)
{
- if (!loader) return;
+ if (!loader)
+ return;
if (!--loader->ref_count)
exif_loader_free (loader);
}
@@ -316,7 +374,8 @@ exif_loader_unref (ExifLoader *loader)
void
exif_loader_reset (ExifLoader *loader)
{
- if (!loader) return;
+ if (!loader)
+ return;
exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
loader->size = 0;
loader->bytes_read = 0;
@@ -330,7 +389,9 @@ exif_loader_get_data (ExifLoader *loader)
{
ExifData *ed;
- if (!loader) return NULL;
+ if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN) ||
+ !loader->bytes_read)
+ return NULL;
ed = exif_data_new_mem (loader->mem);
exif_data_log (ed, loader->log);
@@ -342,7 +403,8 @@ exif_loader_get_data (ExifLoader *loader)
void
exif_loader_log (ExifLoader *loader, ExifLog *log)
{
- if (!loader) return;
+ if (!loader)
+ return;
exif_log_unref (loader->log);
loader->log = log;
exif_log_ref (log);