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.
21
#include "jpeg-data.h"
29
struct _JPEGDataPrivate
31
unsigned int ref_count;
39
data = malloc (sizeof (JPEGData));
42
memset (data, 0, sizeof (JPEGData));
43
data->priv = malloc (sizeof (JPEGDataPrivate));
48
memset (data->priv, 0, sizeof (JPEGDataPrivate));
49
data->priv->ref_count = 1;
55
jpeg_data_append_section (JPEGData *data)
60
s = malloc (sizeof (JPEGSection));
62
s = realloc (data->sections,
63
sizeof (JPEGSection) * (data->count + 1));
72
jpeg_data_save_file (JPEGData *data, const char *path)
75
unsigned char *d = NULL;
76
unsigned int size = 0;
78
jpeg_data_save_data (data, &d, &size);
83
f = fopen (path, "wb");
88
fwrite (d, sizeof (char), size, f);
94
jpeg_data_save_data (JPEGData *data, unsigned char **d, unsigned int *ds)
96
unsigned int i, eds = 0;
98
unsigned char *ed = NULL;
107
for (*ds = i = 0; i < data->count; i++) {
108
s = data->sections[i];
110
printf ("Writing marker 0x%x at position %i...\n",
114
/* Write the marker */
115
*d = realloc (*d, sizeof (char) * (*ds + 2));
116
(*d)[*ds + 0] = 0xff;
117
(*d)[*ds + 1] = s.marker;
121
case JPEG_MARKER_SOI:
122
case JPEG_MARKER_EOI:
124
case JPEG_MARKER_APP1:
125
exif_data_save_data (s.content.app1, &ed, &eds);
127
*d = realloc (*d, sizeof (char) * (*ds + 2));
128
(*d)[*ds + 0] = (eds + 2) >> 8;
129
(*d)[*ds + 1] = (eds + 2) >> 0;
131
*d = realloc (*d, sizeof (char) * (*ds + eds));
132
memcpy (*d + *ds, ed, eds);
137
*d = realloc (*d, sizeof (char) *
138
(*ds + s.content.generic.size + 2));
139
(*d)[*ds + 0] = (s.content.generic.size + 2) >> 8;
140
(*d)[*ds + 1] = (s.content.generic.size + 2) >> 0;
142
memcpy (*d + *ds, s.content.generic.data,
143
s.content.generic.size);
144
*ds += s.content.generic.size;
146
/* In case of SOS, we need to write the data. */
147
if (s.marker == JPEG_MARKER_SOS) {
148
*d = realloc (*d, *ds + data->size);
149
memcpy (*d + *ds, data->data, data->size);
158
jpeg_data_new_from_data (const unsigned char *d,
163
data = jpeg_data_new ();
164
jpeg_data_load_data (data, d, size);
169
jpeg_data_load_data (JPEGData *data, const unsigned char *d,
172
unsigned int i, o, len;
182
printf ("Parsing %i bytes...\n", size);
185
for (o = 0; o < size;) {
188
* JPEG sections start with 0xff. The first byte that is
189
* not 0xff is a marker (hopefully).
191
for (i = 0; i < 7; i++)
192
if (d[o + i] != 0xff)
194
if (!JPEG_IS_MARKER (d[o + i]))
199
printf ("Found marker 0x%x ('%s') at %i.\n", marker,
200
jpeg_marker_get_name (marker), o + i);
203
/* Append this section */
204
jpeg_data_append_section (data);
205
s = &data->sections[data->count - 1];
207
s->content.generic.data = NULL;
211
case JPEG_MARKER_SOI:
212
case JPEG_MARKER_EOI:
216
/* Read the length of the section */
217
len = ((d[o] << 8) | d[o + 1]) - 2;
218
if (len > size) { o = size; break; }
220
if (o + len > size) { o = size; break; }
223
case JPEG_MARKER_APP1:
224
s->content.app1 = exif_data_new_from_data (
228
s->content.generic.size = len;
229
s->content.generic.data =
230
malloc (sizeof (char) * len);
231
memcpy (s->content.generic.data, &d[o], len);
233
/* In case of SOS, image data will follow. */
234
if (s->marker == JPEG_MARKER_SOS) {
235
data->size = size - 2 - o - len;
236
data->data = malloc (
237
sizeof (char) * data->size);
238
memcpy (data->data, d + o + len,
251
jpeg_data_new_from_file (const char *path)
255
data = jpeg_data_new ();
256
jpeg_data_load_file (data, path);
261
jpeg_data_load_file (JPEGData *data, const char *path)
272
f = fopen (path, "rb");
276
/* For now, we read the data into memory. Patches welcome... */
277
fseek (f, 0, SEEK_END);
279
fseek (f, 0, SEEK_SET);
280
d = malloc (sizeof (char) * size);
285
if (fread (d, 1, size, f) != size) {
292
jpeg_data_load_data (data, d, size);
297
jpeg_data_ref (JPEGData *data)
302
data->priv->ref_count++;
306
jpeg_data_unref (JPEGData *data)
311
data->priv->ref_count--;
312
if (!data->priv->ref_count)
313
jpeg_data_free (data);
317
jpeg_data_free (JPEGData *data)
326
for (i = 0; i < data->count; i++) {
327
s = data->sections[i];
329
case JPEG_MARKER_SOI:
330
case JPEG_MARKER_EOI:
332
case JPEG_MARKER_APP1:
333
exif_data_unref (s.content.app1);
336
free (s.content.generic.data);
340
free (data->sections);
350
jpeg_data_dump (JPEGData *data)
359
printf ("Dumping JPEG data (%i bytes of data)...\n", data->size);
360
for (i = 0; i < data->count; i++) {
361
marker = data->sections[i].marker;
362
content = data->sections[i].content;
363
printf ("Section %i (marker 0x%x - %s):\n", i, marker,
364
jpeg_marker_get_name (marker));
365
printf (" Description: %s\n",
366
jpeg_marker_get_description (marker));
368
case JPEG_MARKER_SOI:
369
case JPEG_MARKER_EOI:
371
case JPEG_MARKER_APP1:
372
exif_data_dump (content.app1);
375
printf (" Size: %i\n", content.generic.size);
376
printf (" Unknown content.\n");
383
jpeg_data_get_section (JPEGData *data, JPEGMarker marker)
390
for (i = 0; i < data->count; i++)
391
if (data->sections[i].marker == marker)
392
return (&data->sections[i]);
397
jpeg_data_get_exif_data (JPEGData *data)
399
JPEGSection *section;
404
section = jpeg_data_get_section (data, JPEG_MARKER_APP1);
406
exif_data_ref (section->content.app1);
407
return (section->content.app1);
414
jpeg_data_set_exif_data (JPEGData *data, ExifData *exif_data)
416
JPEGSection *section;
418
section = jpeg_data_get_section (data, JPEG_MARKER_APP1);
420
jpeg_data_append_section (data);
421
memmove (&data->sections[2], &data->sections[1],
422
sizeof (JPEGSection) * (data->count - 2));
423
section = &data->sections[1];
425
section->marker = JPEG_MARKER_APP1;
426
section->content.app1 = exif_data;
427
exif_data_ref (exif_data);