libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

jpeg_extractor.c
Go to the documentation of this file.
1 /*
2  This file is part of libextractor.
3  Copyright (C) 2002, 2003, 2004, 2012 Vidyut Samanta and Christian Grothoff
4 
5  libextractor is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published
7  by the Free Software Foundation; either version 3, or (at your
8  option) any later version.
9 
10  libextractor is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with libextractor; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19  */
20 /**
21  * @file plugins/jpeg_extractor.c
22  * @brief plugin to support JPEG files
23  * @author Christian Grothoff
24  */
25 #include "platform.h"
26 #include "extractor.h"
27 #if WINDOWS || DARWIN
28 #if DARWIN
29 typedef int boolean;
30 #endif
31 #define HAVE_BOOLEAN
32 #endif
33 #include <jpeglib.h>
34 #include <setjmp.h>
35 
36 
37 /**
38  * Context for custom functions.
39  */
40 struct Context
41 {
42  /**
43  * Environment for longjmp from within error_exit handler.
44  */
45  jmp_buf env;
46 };
47 
48 
49 /**
50  * Function used to avoid having libjpeg write error messages to the console.
51  */
52 static void
53 no_emit (j_common_ptr cinfo, int msg_level)
54 {
55  /* do nothing */
56 }
57 
58 
59 /**
60  * Function used to avoid having libjpeg write error messages to the console.
61  */
62 static void
63 no_output (j_common_ptr cinfo)
64 {
65  /* do nothing */
66 }
67 
68 
69 /**
70  * Function used to avoid having libjpeg kill our process.
71  */
72 static void
73 no_exit (j_common_ptr cinfo)
74 {
75  struct Context *ctx = cinfo->client_data;
76 
77  /* we're not allowed to return (by API definition),
78  and we don't want to abort/exit. So we longjmp
79  to our cleanup code instead. */
80  longjmp (ctx->env, 1);
81 }
82 
83 
84 /**
85  * Main entry method for the 'image/jpeg' extraction plugin.
86  *
87  * @param ec extraction context provided to the plugin
88  */
89 void
91 {
92  struct jpeg_decompress_struct jds;
93  struct jpeg_error_mgr em;
94  void *buf;
95  ssize_t size;
96  int is_jpeg;
97  unsigned int rounds;
98  char format[128];
99  struct jpeg_marker_struct *mptr;
100  struct Context ctx;
101 
102  is_jpeg = 0;
103  rounds = 0; /* used to avoid going on forever for non-jpeg files */
104  jpeg_std_error (&em);
105  em.emit_message = &no_emit;
106  em.output_message = &no_output;
107  em.error_exit = &no_exit;
108  jds.client_data = &ctx;
109  if (1 == setjmp (ctx.env))
110  goto EXIT; /* we get here if libjpeg calls 'no_exit' because it wants to die */
111  jds.err = &em;
112  jpeg_create_decompress (&jds);
113  jpeg_save_markers (&jds, JPEG_COM, 1024 * 8);
114  while ( (1 == is_jpeg) || (rounds++ < 8) )
115  {
116  if (-1 == (size = ec->read (ec->cls,
117  &buf,
118  16 * 1024)))
119  break;
120  if (0 == size)
121  break;
122  jpeg_mem_src (&jds, buf, size);
123  if (0 == is_jpeg)
124  {
125  if (JPEG_HEADER_OK == jpeg_read_header (&jds, 1))
126  is_jpeg = 1; /* ok, really a jpeg, keep going until the end */
127  continue;
128  }
129  jpeg_consume_input (&jds);
130  }
131 
132  if (1 != is_jpeg)
133  goto EXIT;
134  if (0 !=
135  ec->proc (ec->cls,
136  "jpeg",
139  "text/plain",
140  "image/jpeg",
141  strlen ("image/jpeg") + 1))
142  goto EXIT;
143  snprintf (format,
144  sizeof (format),
145  "%ux%u",
146  (unsigned int) jds.image_width,
147  (unsigned int) jds.image_height);
148  if (0 !=
149  ec->proc (ec->cls,
150  "jpeg",
153  "text/plain",
154  format,
155  strlen (format) + 1))
156  goto EXIT;
157  for (mptr = jds.marker_list; NULL != mptr; mptr = mptr->next)
158  {
159  size_t off;
160 
161  if (JPEG_COM != mptr->marker)
162  continue;
163  off = 0;
164  while ( (off < mptr->data_length) &&
165  (isspace (((const unsigned char *) mptr->data)[mptr->data_length
166  - 1 - off])) )
167  off++;
168  if (0 !=
169  ec->proc (ec->cls,
170  "jpeg",
173  "text/plain",
174  (const char *) mptr->data,
175  mptr->data_length - off))
176  goto EXIT;
177  }
178 
179 EXIT:
180  jpeg_destroy_decompress (&jds);
181 }
182 
183 
184 /* end of jpeg_extractor.c */
@ EXTRACTOR_METAFORMAT_C_STRING
Definition: extractor.h:113
@ EXTRACTOR_METAFORMAT_UTF8
Definition: extractor.h:102
#define NULL
Definition: getopt1.c:60
@ EXTRACTOR_METATYPE_COMMENT
Definition: extractor.h:131
@ EXTRACTOR_METATYPE_MIMETYPE
Definition: extractor.h:129
@ EXTRACTOR_METATYPE_IMAGE_DIMENSIONS
Definition: extractor.h:257
void EXTRACTOR_jpeg_extract_method(struct EXTRACTOR_ExtractContext *ec)
static void no_output(j_common_ptr cinfo)
static void no_emit(j_common_ptr cinfo, int msg_level)
static void no_exit(j_common_ptr cinfo)
plaform specifics
jmp_buf env
EXTRACTOR_MetaDataProcessor proc
Definition: extractor.h:525
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494