3
* Copyright � 2001 Lutz M�ller <lutz@users.sourceforge.net>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
22
#include "jpeg-data.h"
30
struct _JPEGDataPrivate
32
unsigned int ref_count;
40
data = malloc (sizeof (JPEGData));
43
memset (data, 0, sizeof (JPEGData));
44
data->priv = malloc (sizeof (JPEGDataPrivate));
49
memset (data->priv, 0, sizeof (JPEGDataPrivate));
50
data->priv->ref_count = 1;
56
jpeg_data_append_section (JPEGData *data)
61
s = malloc (sizeof (JPEGSection));
63
s = realloc (data->sections,
64
sizeof (JPEGSection) * (data->count + 1));
72
/* jpeg_data_save_file returns 1 on succes, 0 on failure */
74
jpeg_data_save_file (JPEGData *data, const char *path)
77
unsigned char *d = NULL;
78
unsigned int size = 0, written;
80
jpeg_data_save_data (data, &d, &size);
85
f = fopen (path, "wb");
90
written = fwrite (d, 1, size, f);
93
if (written == size) {
101
jpeg_data_save_data (JPEGData *data, unsigned char **d, unsigned int *ds)
103
unsigned int i, eds = 0;
105
unsigned char *ed = NULL;
114
for (*ds = i = 0; i < data->count; i++) {
115
s = data->sections[i];
117
printf ("Writing marker 0x%x at position %i...\n",
121
/* Write the marker */
122
*d = realloc (*d, sizeof (char) * (*ds + 2));
123
(*d)[*ds + 0] = 0xff;
124
(*d)[*ds + 1] = s.marker;
128
case JPEG_MARKER_SOI:
129
case JPEG_MARKER_EOI:
131
case JPEG_MARKER_APP1:
132
exif_data_save_data (s.content.app1, &ed, &eds);
134
*d = realloc (*d, sizeof (char) * (*ds + 2));
135
(*d)[*ds + 0] = (eds + 2) >> 8;
136
(*d)[*ds + 1] = (eds + 2) >> 0;
138
*d = realloc (*d, sizeof (char) * (*ds + eds));
139
memcpy (*d + *ds, ed, eds);
144
*d = realloc (*d, sizeof (char) *
145
(*ds + s.content.generic.size + 2));
146
(*d)[*ds + 0] = (s.content.generic.size + 2) >> 8;
147
(*d)[*ds + 1] = (s.content.generic.size + 2) >> 0;
149
memcpy (*d + *ds, s.content.generic.data,
150
s.content.generic.size);
151
*ds += s.content.generic.size;
153
/* In case of SOS, we need to write the data. */
154
if (s.marker == JPEG_MARKER_SOS) {
155
*d = realloc (*d, *ds + data->size);
156
memcpy (*d + *ds, data->data, data->size);
165
jpeg_data_new_from_data (const unsigned char *d,
170
data = jpeg_data_new ();
171
jpeg_data_load_data (data, d, size);
176
jpeg_data_load_data (JPEGData *data, const unsigned char *d,
179
unsigned int i, o, len;
189
printf ("Parsing %i bytes...\n", size);
192
for (o = 0; o < size;) {
195
* JPEG sections start with 0xff. The first byte that is
196
* not 0xff is a marker (hopefully).
198
for (i = 0; i < 7; i++)
199
if (d[o + i] != 0xff)
201
if (!JPEG_IS_MARKER (d[o + i]))
206
printf ("Found marker 0x%x ('%s') at %i.\n", marker,
207
jpeg_marker_get_name (marker), o + i);
210
/* Append this section */
211
jpeg_data_append_section (data);
212
s = &data->sections[data->count - 1];
214
s->content.generic.data = NULL;
218
case JPEG_MARKER_SOI:
219
case JPEG_MARKER_EOI:
223
/* Read the length of the section */
224
len = ((d[o] << 8) | d[o + 1]) - 2;
225
if (len > size) { o = size; break; }
227
if (o + len > size) { o = size; break; }
230
case JPEG_MARKER_APP1:
231
s->content.app1 = exif_data_new_from_data (
235
s->content.generic.size = len;
236
s->content.generic.data =
237
malloc (sizeof (char) * len);
238
memcpy (s->content.generic.data, &d[o], len);
240
/* In case of SOS, image data will follow. */
241
if (s->marker == JPEG_MARKER_SOS) {
242
data->size = size - 2 - o - len;
243
data->data = malloc (
244
sizeof (char) * data->size);
245
memcpy (data->data, d + o + len,
258
jpeg_data_new_from_file (const char *path)
262
data = jpeg_data_new ();
263
jpeg_data_load_file (data, path);
268
jpeg_data_load_file (JPEGData *data, const char *path)
279
f = fopen (path, "rb");
283
/* For now, we read the data into memory. Patches welcome... */
284
fseek (f, 0, SEEK_END);
286
fseek (f, 0, SEEK_SET);
287
d = malloc (sizeof (char) * size);
292
if (fread (d, 1, size, f) != size) {
299
jpeg_data_load_data (data, d, size);
304
jpeg_data_ref (JPEGData *data)
309
data->priv->ref_count++;
313
jpeg_data_unref (JPEGData *data)
318
data->priv->ref_count--;
319
if (!data->priv->ref_count)
320
jpeg_data_free (data);
324
jpeg_data_free (JPEGData *data)
333
for (i = 0; i < data->count; i++) {
334
s = data->sections[i];
336
case JPEG_MARKER_SOI:
337
case JPEG_MARKER_EOI:
339
case JPEG_MARKER_APP1:
340
exif_data_unref (s.content.app1);
343
free (s.content.generic.data);
347
free (data->sections);
357
jpeg_data_dump (JPEGData *data)
366
printf ("Dumping JPEG data (%i bytes of data)...\n", data->size);
367
for (i = 0; i < data->count; i++) {
368
marker = data->sections[i].marker;
369
content = data->sections[i].content;
370
printf ("Section %i (marker 0x%x - %s):\n", i, marker,
371
jpeg_marker_get_name (marker));
372
printf (" Description: %s\n",
373
jpeg_marker_get_description (marker));
375
case JPEG_MARKER_SOI:
376
case JPEG_MARKER_EOI:
378
case JPEG_MARKER_APP1:
379
exif_data_dump (content.app1);
382
printf (" Size: %i\n", content.generic.size);
383
printf (" Unknown content.\n");
390
jpeg_data_get_section (JPEGData *data, JPEGMarker marker)
397
for (i = 0; i < data->count; i++)
398
if (data->sections[i].marker == marker)
399
return (&data->sections[i]);
404
jpeg_data_get_exif_data (JPEGData *data)
406
JPEGSection *section;
411
section = jpeg_data_get_section (data, JPEG_MARKER_APP1);
413
exif_data_ref (section->content.app1);
414
return (section->content.app1);
421
jpeg_data_set_exif_data (JPEGData *data, ExifData *exif_data)
423
JPEGSection *section;
425
section = jpeg_data_get_section (data, JPEG_MARKER_APP1);
427
jpeg_data_append_section (data);
428
memmove (&data->sections[2], &data->sections[1],
429
sizeof (JPEGSection) * (data->count - 2));
430
section = &data->sections[1];
432
exif_data_unref (section->content.app1);
434
section->marker = JPEG_MARKER_APP1;
435
section->content.app1 = exif_data;
436
exif_data_ref (exif_data);