Update of /cvsroot/libexif/libexif/libexif
In directory sc8-pr-cvs1:/tmp/cvs-serv23454/libexif
Added Files:
exif-loader.c exif-loader.h
Log Message:
2003-03-17 Lutz Mueller <lu...@us...>
* libexif/exif-loader.[c,h]: New. Mostly written by Jens Finke
<je...@tr...>. Not tested at all.
--- NEW FILE: exif-loader.c ---
#include <config.h>
#include "exif-loader.h"
#include <stdlib.h>
#include <string.h>
#include <libjpeg/jpeg-marker.h>
typedef enum {
EL_READ = 0,
EL_READ_SIZE_HIGH_BYTE,
EL_READ_SIZE_LOW_BYTE,
EL_SKIP_BYTES,
EL_EXIF_FOUND,
EL_FAILED
} ExifLoaderState;
struct _ExifLoader {
ExifLoaderState state;
int size;
int last_marker;
unsigned char *buf;
int bytes_read;
unsigned int ref_count;
};
#undef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
/* This function imitates code from libexif, written by Lutz
* Müller. See libexif/exif-data.c:exif_data_new_from_file. Here, it
* can cope with a sequence of data chunks.
*/
unsigned char
exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
{
int i;
int len_remain;
if (!eld) return 0;
if (eld->state == EL_FAILED) return 0;
if (eld->size && eld->bytes_read == eld->size) return 0;
for (i = 0; (i < len) && (eld->state != EL_EXIF_FOUND) &&
(eld->state != EL_FAILED); i++) {
switch (eld->state) {
case EL_SKIP_BYTES:
eld->size--;
if (eld->size == 0) {
eld->state = EL_READ;
}
break;
case EL_READ_SIZE_HIGH_BYTE:
eld->size = buf [i] << 8;
eld->state = EL_READ_SIZE_LOW_BYTE;
break;
case EL_READ_SIZE_LOW_BYTE:
eld->size |= buf [i];
switch (eld->last_marker) {
case JPEG_MARKER_APP0:
eld->state = EL_SKIP_BYTES;
break;
case JPEG_MARKER_APP1:
eld->state = EL_EXIF_FOUND;
break;
case 0:
/*
* Assume that we are reading EXIF data.
* This should probably be verified by reading
* some bytes ahead.
*/
eld->state = EL_EXIF_FOUND;
break;
default:
return 0;
}
eld->last_marker = 0;
break;
default:
if (buf[i] != 0xff) {
if (buf [i] == JPEG_MARKER_APP0 ||
buf [i] == JPEG_MARKER_APP1) {
eld->state = EL_READ_SIZE_HIGH_BYTE;
eld->last_marker = buf [i];
} else if (buf [i] == JPEG_MARKER_SOI) {
/* Nothing */
} else {
/* Assume that we are reading EXIF
* data. This should probably be
* verified by reading some bytes
* ahead.
*/
eld->last_marker = JPEG_MARKER_APP1;
eld->state = EL_READ_SIZE_HIGH_BYTE;
i--;
}
}
}
}
len_remain = len - i;
if (!len_remain) return 1;
if (eld->state == EL_EXIF_FOUND && len_remain > 0) {
if (eld->buf == NULL) {
eld->buf = malloc (sizeof (unsigned char) * eld->size);
eld->bytes_read = 0;
}
if (eld->bytes_read < eld->size) {
int cp_len;
/* the number of bytes we need to copy */
cp_len = MIN (eld->size - eld->bytes_read, len_remain);
if ((cp_len + eld->bytes_read) > eld->size) return 1;
/* Copy memory */
memcpy (eld->buf + eld->bytes_read, &buf[i], cp_len);
eld->bytes_read += cp_len;
}
}
return 1;
}
ExifLoader *
exif_loader_new (void)
{
ExifLoader *loader = malloc (sizeof (ExifLoader));
memset (loader, 0, sizeof (ExifLoader));
return loader;
}
void
exif_loader_ref (ExifLoader *loader)
{
if (loader) loader->ref_count++;
}
void
exif_loader_unref (ExifLoader *loader)
{
if (!loader) return;
if (!--loader->ref_count) {
exif_loader_reset (loader);
free (loader);
}
}
void
exif_loader_reset (ExifLoader *loader)
{
if (!loader) return;
free (loader->buf); loader->buf = NULL;
}
ExifData *
exif_loader_get_data (ExifLoader *loader)
{
return exif_data_new_from_data (loader->buf, loader->bytes_read);
}
--- NEW FILE: exif-loader.h ---
(This appears to be a binary file; contents omitted.)
|