main.html
Main Page
|
classes.html
Alphabetical List
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
functions.html
Data Fields
|
globals.html
Globals
dir_000000.html
libexif
exif-loader.c
exif-loader_8c.html
Go to the documentation of this file.
00001
/* exif-loader.c
00002
*
00003
* Copyright ? 2002 Lutz M?ller <lutz@users.sourceforge.net>
00004
*
00005
* This library is free software; you can redistribute it and/or
00006
* modify it under the terms of the GNU Lesser General Public
00007
* License as published by the Free Software Foundation; either
00008
* version 2 of the License, or (at your option) any later version.
00009
*
00010
* This library is distributed in the hope that it will be useful,
00011
* but WITHOUT ANY WARRANTY; without even the implied warranty of
00012
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013
* Lesser General Public License for more details.
00014
*
00015
* You should have received a copy of the GNU Lesser General Public
00016
* License along with this library; if not, write to the
00017
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018
* Boston, MA 02111-1307, USA.
00019
*/
00020
00021
#include <config.h>
00022
00023
#include <
exif-loader_8h.html
libexif/exif-loader.h
>
00024
#include <
i18n_8h.html
libexif/i18n.h
>
00025
00026
#include <stdlib.h>
00027
#include <string.h>
00028
#include <stdio.h>
00029
00030
#undef JPEG_MARKER_SOI
exif-loader_8c.html#a0
00031
#define JPEG_MARKER_SOI  0xd8
00032
#undef JPEG_MARKER_APP0
exif-loader_8c.html#a1
00033
#define JPEG_MARKER_APP0 0xe0
00034
#undef JPEG_MARKER_APP1
exif-loader_8c.html#a2
00035
#define JPEG_MARKER_APP1 0xe1
00036
#undef JPEG_MARKER_APP13
exif-loader_8c.html#a3
00037
#define JPEG_MARKER_APP13 0xed
00038
#undef JPEG_MARKER_COM
exif-loader_8c.html#a4
00039
#define JPEG_MARKER_COM 0xfe
00040
exif-loader_8c.html#a30
00041
typedef
enum
{
00042
exif-loader_8c.html#a30a7
EL_READ
= 0,
00043
exif-loader_8c.html#a30a8
EL_READ_SIZE_BYTE_24
,
00044
exif-loader_8c.html#a30a9
EL_READ_SIZE_BYTE_16
,
00045
exif-loader_8c.html#a30a10
EL_READ_SIZE_BYTE_08
,
00046
exif-loader_8c.html#a30a11
EL_READ_SIZE_BYTE_00
,
00047
exif-loader_8c.html#a30a12
EL_SKIP_BYTES
,
00048
exif-loader_8c.html#a30a13
EL_EXIF_FOUND
,
00049 }
exif-loader_8c.html#a30
ExifLoaderState
;
00050
exif-loader_8c.html#a31
00051
typedef
enum
{
00052
exif-loader_8c.html#a31a14
EL_DATA_FORMAT_UNKNOWN
,
00053
exif-loader_8c.html#a31a15
EL_DATA_FORMAT_EXIF
,
00054
exif-loader_8c.html#a31a16
EL_DATA_FORMAT_JPEG
,
00055
exif-loader_8c.html#a31a17
EL_DATA_FORMAT_FUJI_RAW
00056 }
exif-loader_8c.html#a31
ExifLoaderDataFormat
;
00057
struct__ExifLoader.html
00058
struct
struct__ExifLoader.html
_ExifLoader
{
struct__ExifLoader.html#o0
00059
exif-loader_8c.html#a30
ExifLoaderState
struct__ExifLoader.html#o0
state
;
struct__ExifLoader.html#o1
00060
exif-loader_8c.html#a31
ExifLoaderDataFormat
struct__ExifLoader.html#o1
data_format
;
00061
00062
/* Small buffer used for detection of format */
struct__ExifLoader.html#o2
00063
unsigned
char
struct__ExifLoader.html#o2
b
[12];
struct__ExifLoader.html#o3
00064
unsigned
char
struct__ExifLoader.html#o3
b_len
;
00065
struct__ExifLoader.html#o4
00066
unsigned
int
struct__ExifLoader.html#o4
size
;
struct__ExifLoader.html#o5
00067
unsigned
char
*
struct__ExifLoader.html#o5
buf
;
struct__ExifLoader.html#o6
00068
unsigned
int
struct__ExifLoader.html#o6
bytes_read
;
00069
struct__ExifLoader.html#o7
00070
unsigned
int
struct__ExifLoader.html#o7
ref_count
;
00071
struct__ExifLoader.html#o8
00072
struct__ExifLog.html
ExifLog
*
struct__ExifLoader.html#o8
log
;
struct__ExifLoader.html#o9
00073
struct__ExifMem.html
ExifMem
*
struct__ExifLoader.html#o9
mem
;
00074 };
00075
exif-loader_8c.html#a6
00076
static
const
unsigned
char
exif-data_8c.html#a6
ExifHeader
[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
00077
00078
static
void
*
exif-loader_8c.html#a18
00079
exif-loader_8c.html#a18
exif_loader_alloc
(
struct__ExifLoader.html
ExifLoader
*l,
unsigned
int
i)
00080 {
00081
void
*d;
00082
00083
if
(!l || !i)
return
NULL;
00084
00085         d =
exif-mem_8c.html#a7
exif_mem_alloc
(l->
struct__ExifLoader.html#o9
mem
, i);
00086
if
(d)
return
d;
00087
00088
exif-log_8h.html#a0
EXIF_LOG_NO_MEMORY
(l->
struct__ExifLoader.html#o8
log
,
"ExifLog"
, i);
00089
return
NULL;
00090 }
00091
00092
#undef  MIN
exif-loader_8c.html#a5
00093
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
00094
00095
void
exif-loader_8h.html#a5
00096
exif-loader_8c.html#a19
exif_loader_write_file
(
struct__ExifLoader.html
ExifLoader
*l,
const
char
*path)
00097 {
00098         FILE *f;
00099
int
exif-format_8c.html#a2
size
;
00100
unsigned
char
data[1024];
00101
00102
if
(!l)
return
;
00103
00104         f = fopen (path,
"rb"
);
00105
if
(!f) {
00106
exif-log_8c.html#a12
exif_log
(l->
struct__ExifLoader.html#o8
log
,
exif-log_8h.html#a17a3
EXIF_LOG_CODE_NONE
,
"ExifLoader"
,
00107
i18n_8h.html#a6
_
(
"The file '%s' could not be opened."
), path);
00108
return
;
00109         }
00110
while
(1) {
00111                 size = fread (data, 1,
sizeof
(data), f);
00112
if
(size <= 0)
break
;
00113
if
(!
exif-loader_8c.html#a21
exif_loader_write
(l, data, size))
break
;
00114         }
00115         fclose (f);
00116 }
00117
00118
static
unsigned
int
exif-loader_8c.html#a20
00119
exif-loader_8c.html#a20
exif_loader_copy
(
struct__ExifLoader.html
ExifLoader
*eld,
unsigned
char
*buf,
unsigned
int
len)
00120 {
00121
if
(!eld || (len && !buf) || (eld->
struct__ExifLoader.html#o6
bytes_read
>= eld->
struct__ExifLoader.html#o4
size
))
return
0;
00122
00123
/* If needed, allocate the buffer. */
00124
if
(!eld->
struct__ExifLoader.html#o5
buf
) eld->
struct__ExifLoader.html#o5
buf
=
exif-loader_8c.html#a18
exif_loader_alloc
(eld, eld->
struct__ExifLoader.html#o4
size
);
00125
if
(!eld->
struct__ExifLoader.html#o5
buf
)
return
0;
00126
00127
/* Copy memory */
00128         len =
exif-loader_8c.html#a5
MIN
(len, eld->
struct__ExifLoader.html#o4
size
- eld->
struct__ExifLoader.html#o6
bytes_read
);
00129         memcpy (eld->
struct__ExifLoader.html#o5
buf
+ eld->
struct__ExifLoader.html#o6
bytes_read
, buf, len);
00130         eld->
struct__ExifLoader.html#o6
bytes_read
+= len;
00131
00132
return
(eld->
struct__ExifLoader.html#o6
bytes_read
>= eld->
struct__ExifLoader.html#o4
size
) ? 0 : 1;
00133 }
00134
00135
unsigned
char
exif-loader_8h.html#a6
00136
exif-loader_8c.html#a21
exif_loader_write
(
struct__ExifLoader.html
ExifLoader
*eld,
unsigned
char
*buf,
unsigned
int
len)
00137 {
00138
unsigned
int
i;
00139
00140
if
(!eld || (len && !buf))
return
0;
00141
00142
switch
(eld->
struct__ExifLoader.html#o0
state
) {
00143
case
exif-loader_8c.html#a30a13
EL_EXIF_FOUND
:
00144
return
exif-loader_8c.html#a20
exif_loader_copy
(eld, buf, len);
00145
case
exif-loader_8c.html#a30a12
EL_SKIP_BYTES
:
00146
if
(eld->
struct__ExifLoader.html#o4
size
> len) { eld->
struct__ExifLoader.html#o4
size
-= len;
return
1; }
00147                 len -= eld->
struct__ExifLoader.html#o4
size
;
00148                 buf += eld->
struct__ExifLoader.html#o4
size
;
00149                 eld->
struct__ExifLoader.html#o4
size
= 0;
00150                 eld->
struct__ExifLoader.html#o3
b_len
= 0;
00151
switch
(eld->
struct__ExifLoader.html#o1
data_format
) {
00152
case
exif-loader_8c.html#a31a17
EL_DATA_FORMAT_FUJI_RAW
:
00153                         eld->
struct__ExifLoader.html#o0
state
=
exif-loader_8c.html#a30a8
EL_READ_SIZE_BYTE_24
;
00154
break
;
00155
default
:
00156                         eld->
struct__ExifLoader.html#o0
state
=
exif-loader_8c.html#a30a7
EL_READ
;
00157
break
;
00158                 }
00159
break
;
00160
default
:
00161
break
;
00162         }
00163
00164
exif-log_8c.html#a12
exif_log
(eld->
struct__ExifLoader.html#o8
log
,
exif-log_8h.html#a17a4
EXIF_LOG_CODE_DEBUG
,
"ExifLoader"
,
00165
"Scanning %i byte(s) of data..."
, len);
00166
00167
/*
00168
* First fill the small buffer. Only continue if the buffer
00169
* is filled. Note that EXIF data contains at least 12 bytes.
00170
*/
00171         i =
exif-loader_8c.html#a5
MIN
(len,
sizeof
(eld->
struct__ExifLoader.html#o2
b
) - eld->
struct__ExifLoader.html#o3
b_len
);
00172
if
(i) {
00173                 memcpy (&eld->
struct__ExifLoader.html#o2
b
[eld->
struct__ExifLoader.html#o3
b_len
], buf, i);
00174                 eld->
struct__ExifLoader.html#o3
b_len
+= i;
00175
if
(eld->
struct__ExifLoader.html#o3
b_len
< sizeof (eld->
struct__ExifLoader.html#o2
b
))
return
1;
00176                 buf += i;
00177                 len -= i;
00178         }
00179
00180
switch
(eld->
struct__ExifLoader.html#o1
data_format
) {
00181
case
exif-loader_8c.html#a31a14
EL_DATA_FORMAT_UNKNOWN
:
00182
00183
/* Check the small buffer against known formats. */
00184
if
(!memcmp (eld->
struct__ExifLoader.html#o2
b
,
"FUJIFILM"
, 8)) {
00185
00186
/* Skip to byte 84. There is another offset there. */
00187                         eld->
struct__ExifLoader.html#o1
data_format
=
exif-loader_8c.html#a31a17
EL_DATA_FORMAT_FUJI_RAW
;
00188                         eld->
struct__ExifLoader.html#o4
size
= 84;
00189                         eld->
struct__ExifLoader.html#o0
state
=
exif-loader_8c.html#a30a12
EL_SKIP_BYTES
;
00190                         eld->
struct__ExifLoader.html#o4
size
= 84;
00191
00192                 }
else
if
(!memcmp (eld->
struct__ExifLoader.html#o2
b
+ 2,
exif-data_8c.html#a6
ExifHeader
, sizeof (
exif-data_8c.html#a6
ExifHeader
))) {
00193
00194
/* Read the size (2 bytes). */
00195                         eld->
struct__ExifLoader.html#o1
data_format
=
exif-loader_8c.html#a31a15
EL_DATA_FORMAT_EXIF
;
00196                         eld->
struct__ExifLoader.html#o0
state
=
exif-loader_8c.html#a30a10
EL_READ_SIZE_BYTE_08
;
00197                 }
00198
default
:
00199
break
;
00200         }
00201
00202
for
(i = 0; i <
sizeof
(eld->
struct__ExifLoader.html#o2
b
); i++)
00203
switch
(eld->
struct__ExifLoader.html#o0
state
) {
00204
case
exif-loader_8c.html#a30a13
EL_EXIF_FOUND
:
00205
if
(!
exif-loader_8c.html#a20
exif_loader_copy
(eld, eld->
struct__ExifLoader.html#o2
b
+ i,
00206                                         sizeof (eld->b) - i))
return
0;
00207
return
exif-loader_8c.html#a20
exif_loader_copy
(eld, buf, len);
00208
case
exif-loader_8c.html#a30a12
EL_SKIP_BYTES
:
00209                         eld->size--;
00210
if
(!eld->size) eld->state =
exif-loader_8c.html#a30a7
EL_READ
;
00211
break
;
00212
00213
case
exif-loader_8c.html#a30a8
EL_READ_SIZE_BYTE_24
:
00214                         eld->size |= eld->b[i] << 24;
00215                         eld->state =
exif-loader_8c.html#a30a9
EL_READ_SIZE_BYTE_16
;
00216
break
;
00217
case
exif-loader_8c.html#a30a9
EL_READ_SIZE_BYTE_16
:
00218                         eld->size |= eld->b[i] << 16;
00219                         eld->state =
exif-loader_8c.html#a30a10
EL_READ_SIZE_BYTE_08
;
00220
break
;
00221
case
exif-loader_8c.html#a30a10
EL_READ_SIZE_BYTE_08
:
00222                         eld->size |= eld->b[i] << 8;
00223                         eld->state =
exif-loader_8c.html#a30a11
EL_READ_SIZE_BYTE_00
;
00224
break
;
00225
case
exif-loader_8c.html#a30a11
EL_READ_SIZE_BYTE_00
:
00226                         eld->size |= eld->b[i] << 0;
00227
switch
(eld->data_format) {
00228
case
exif-loader_8c.html#a31a16
EL_DATA_FORMAT_JPEG
:
00229                                 eld->state =
exif-loader_8c.html#a30a12
EL_SKIP_BYTES
;
00230                                 eld->size -= 2;
00231
break
;
00232
case
exif-loader_8c.html#a31a17
EL_DATA_FORMAT_FUJI_RAW
:
00233                                 eld->data_format =
exif-loader_8c.html#a31a15
EL_DATA_FORMAT_EXIF
;
00234                                 eld->state =
exif-loader_8c.html#a30a12
EL_SKIP_BYTES
;
00235                                 eld->size -= 86;
00236
break
;
00237
case
exif-loader_8c.html#a31a15
EL_DATA_FORMAT_EXIF
:
00238                                 eld->state =
exif-loader_8c.html#a30a13
EL_EXIF_FOUND
;
00239
break
;
00240
default
:
00241
break
;
00242                         }
00243
break
;
00244
00245
default
:
00246
switch
(eld->b[i]) {
00247
case
exif-data_8c.html#a3
JPEG_MARKER_APP1
:
00248                                 eld->data_format =
exif-loader_8c.html#a31a15
EL_DATA_FORMAT_EXIF
;
00249                                 eld->size = 0;
00250                                 eld->state =
exif-loader_8c.html#a30a10
EL_READ_SIZE_BYTE_08
;
00251
break
;
00252
case
exif-data_8c.html#a2
JPEG_MARKER_APP0
:
00253
case
exif-loader_8c.html#a3
JPEG_MARKER_APP13
:
00254
case
exif-loader_8c.html#a4
JPEG_MARKER_COM
:
00255                                 eld->data_format =
exif-loader_8c.html#a31a16
EL_DATA_FORMAT_JPEG
;
00256                                 eld->size = 0;
00257                                 eld->state =
exif-loader_8c.html#a30a10
EL_READ_SIZE_BYTE_08
;
00258
break
;
00259
case
0xff:
00260
case
exif-data_8c.html#a1
JPEG_MARKER_SOI
:
00261
break
;
00262
default
:
00263
exif-log_8c.html#a12
exif_log
(eld->log,
00264
exif-log_8h.html#a17a6
EXIF_LOG_CODE_CORRUPT_DATA
,
00265
"ExifLoader"
,
i18n_8h.html#a6
_
(
"The data supplied "
00266
"does not seem to contain "
00267
"EXIF data."
));
00268
exif-loader_8c.html#a27
exif_loader_reset
(eld);
00269
return
0;
00270                         }
00271                 }
00272
00273
/*
00274
* If we reach this point, the buffer has not been big enough
00275
* to read all data we need. Fill it with new data.
00276
*/
00277         eld->
struct__ExifLoader.html#o3
b_len
= 0;
00278
return
exif-loader_8c.html#a21
exif_loader_write
(eld, buf, len);
00279 }
00280
00281
struct__ExifLoader.html
ExifLoader
*
exif-loader_8h.html#a1
00282
exif-loader_8c.html#a22
exif_loader_new
(
void
)
00283 {
00284
struct__ExifMem.html
ExifMem
*mem =
exif-mem_8c.html#a9
exif_mem_new_default
();
00285
struct__ExifLoader.html
ExifLoader
*l =
exif-loader_8c.html#a23
exif_loader_new_mem
(mem);
00286
00287
exif-mem_8c.html#a5
exif_mem_unref
(mem);
00288
00289
return
l;
00290 }
00291
00292
struct__ExifLoader.html
ExifLoader
*
exif-loader_8h.html#a2
00293
exif-loader_8c.html#a23
exif_loader_new_mem
(
struct__ExifMem.html
ExifMem
*mem)
00294 {
00295
struct__ExifLoader.html
ExifLoader
*loader;
00296
00297
if
(!mem)
return
NULL;
00298
00299         loader =
exif-mem_8c.html#a7
exif_mem_alloc
(mem,
sizeof
(
struct__ExifLoader.html
ExifLoader
));
00300
if
(!loader)
return
NULL;
00301         loader->
struct__ExifLoader.html#o7
ref_count
= 1;
00302
00303         loader->
struct__ExifLoader.html#o9
mem
= mem;
00304
exif-mem_8c.html#a4
exif_mem_ref
(mem);
00305
00306
return
loader;
00307 }
00308
00309
void
exif-loader_8h.html#a3
00310
exif-loader_8c.html#a24
exif_loader_ref
(
struct__ExifLoader.html
ExifLoader
*loader)
00311 {
00312
if
(loader) loader->
struct__ExifLoader.html#o7
ref_count
++;
00313 }
00314
00315
static
void
exif-loader_8c.html#a25
00316
exif-loader_8c.html#a25
exif_loader_free
(
struct__ExifLoader.html
ExifLoader
*loader)
00317 {
00318
struct__ExifMem.html
ExifMem
*mem;
00319
00320
if
(!loader)
return
;
00321
00322         mem = loader->
struct__ExifLoader.html#o9
mem
;
00323
exif-loader_8c.html#a27
exif_loader_reset
(loader);
00324
exif-mem_8c.html#a6
exif_mem_free
(mem, loader);
00325
exif-mem_8c.html#a5
exif_mem_unref
(mem);
00326 }
00327
00328
void
exif-loader_8h.html#a4
00329
exif-loader_8c.html#a26
exif_loader_unref
(
struct__ExifLoader.html
ExifLoader
*loader)
00330 {
00331
if
(!loader)
return
;
00332
if
(!--loader->
struct__ExifLoader.html#o7
ref_count
)
00333
exif-loader_8c.html#a25
exif_loader_free
(loader);
00334 }
00335
00336
void
exif-loader_8h.html#a7
00337
exif-loader_8c.html#a27
exif_loader_reset
(
struct__ExifLoader.html
ExifLoader
*loader)
00338 {
00339
if
(!loader)
return
;
00340
exif-mem_8c.html#a6
exif_mem_free
(loader->
struct__ExifLoader.html#o9
mem
, loader->
struct__ExifLoader.html#o5
buf
); loader->
struct__ExifLoader.html#o5
buf
= NULL;
00341         loader->
struct__ExifLoader.html#o4
size
= 0;
00342         loader->
struct__ExifLoader.html#o6
bytes_read
= 0;
00343         loader->
struct__ExifLoader.html#o0
state
= 0;
00344         loader->
struct__ExifLoader.html#o3
b_len
= 0;
00345         loader->
struct__ExifLoader.html#o1
data_format
=
exif-loader_8c.html#a31a14
EL_DATA_FORMAT_UNKNOWN
;
00346 }
00347
00348
struct__ExifData.html
ExifData
*
exif-loader_8h.html#a8
00349
exif-loader_8c.html#a28
exif_loader_get_data
(
struct__ExifLoader.html
ExifLoader
*loader)
00350 {
00351
struct__ExifData.html
ExifData
*ed;
00352
00353
if
(!loader)
return
NULL;
00354
00355         ed =
exif-data_8c.html#a19
exif_data_new_mem
(loader->
struct__ExifLoader.html#o9
mem
);
00356
exif-data_8c.html#a42
exif_data_log
(ed, loader->
struct__ExifLoader.html#o8
log
);
00357
exif-data_8c.html#a30
exif_data_load_data
(ed, loader->
struct__ExifLoader.html#o5
buf
, loader->
struct__ExifLoader.html#o6
bytes_read
);
00358
00359
return
ed;
00360 }
00361
00362
void
exif-loader_8h.html#a9
00363
exif-loader_8c.html#a29
exif_loader_log
(
struct__ExifLoader.html
ExifLoader
*loader,
struct__ExifLog.html
ExifLog
*log)
00364 {
00365
if
(!loader)
return
;
00366
exif-log_8c.html#a9
exif_log_unref
(loader->
struct__ExifLoader.html#o8
log
);
00367         loader->
struct__ExifLoader.html#o8
log
= log;
00368
exif-log_8c.html#a8
exif_log_ref
(log);
00369 }
Generated on Fri Sep 9 16:28:11 2005 for EXIF library (libexif) Internals by
http://www.doxygen.org/index.html
doxygen
1.4.4
