stop leaking memory through jpeg decoders
[sparrow.git] / jpeg_src.c
blob1855d8aa78b7a3f02528d08bc042c795855a0fe9
1 /************************************************************************************
2 Partially based on TerraLib, from https://svn.dpi.inpe.br/terralib
4 TerraLib - a library for developing GIS applications.
5 Copyright © 2001-2007 INPE and Tecgraf/PUC-Rio.
7 This code is part of the TerraLib library.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 You should have received a copy of the GNU Lesser General Public
14 License along with this library.
16 The authors reassure the license terms regarding the warranties.
17 They specifically disclaim any warranties, including, but not limited to,
18 the implied warranties of merchantability and fitness for a particular purpose.
19 The library provided hereunder is on an "as is" basis, and the authors have no
20 obligation to provide maintenance, support, updates, enhancements, or modifications.
21 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
22 indirect, special, incidental, or consequential damages arising out of the use
23 of this library and its documentation.
24 *************************************************************************************/
26 /* SYNOPSIS
28 GstSparrow *sparrow;
29 guint8 * src; // pointer to jpeg in mem
30 int size; // length of jpeg in mem
31 guint8 * dest; // pointer to output image row
33 init_jpeg_src(sparrow); //once only
35 FOR EACH jpeg {
36 begin_reading_jpeg(sparrow, src, size);
37 FOR EACH line {
38 read_one_line(sparrow, dest);
40 finish_reading_jpeg(sparrow);
43 finalise_jpeg_src(sparrow); // once only (optional really)
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include "jpeglib.h"
50 #include "gstsparrow.h"
51 #include "sparrow.h"
53 // Expanded data source object for memory buffer input
54 typedef struct
56 struct jpeg_source_mgr pub;
57 unsigned char* buffer;
58 unsigned int bufsize;
59 } sparrow_src_mgr;
61 #define COLOURSPACE JCS_EXT_BGRX
65 Initialize source --- Nothing to do
67 static void
68 init_source (j_decompress_ptr cinfo)
72 Fill the input buffer --- called whenever buffer is emptied.
74 static gboolean
75 fill_input_buffer (j_decompress_ptr cinfo)
77 sparrow_src_mgr *src = (sparrow_src_mgr *) cinfo->src;
78 src->pub.next_input_byte = src->buffer;
79 src->pub.bytes_in_buffer = src->bufsize;
81 return TRUE;
85 Skip data --- used to skip over a potentially large amount of
86 uninteresting data.
88 static void
89 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
91 sparrow_src_mgr * src = (sparrow_src_mgr *) cinfo->src;
93 /* just move the ptr */
94 src->pub.next_input_byte += num_bytes;
95 src->pub.bytes_in_buffer -= num_bytes;
99 Terminate source --- called by jpeg_finish_decompress
101 static void
102 term_source (j_decompress_ptr cinfo)
106 Prepare for input from a memory buffer.
108 static void
109 jpeg_mem_src (j_decompress_ptr cinfo, unsigned char* buffer, unsigned int bufsize)
111 sparrow_src_mgr *src;
113 if (cinfo->src == NULL) {
114 cinfo->src = (struct jpeg_source_mgr *)
115 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(sparrow_src_mgr));
118 src = (sparrow_src_mgr *) cinfo->src;
119 src->pub.init_source = init_source;
120 src->pub.fill_input_buffer = fill_input_buffer;
121 src->pub.skip_input_data = skip_input_data;
122 src->pub.resync_to_restart = jpeg_resync_to_restart;
123 src->pub.term_source = term_source;
124 src->pub.bytes_in_buffer = 0;
125 src->pub.next_input_byte = NULL;
127 src->buffer = buffer;
128 src->bufsize = bufsize;
131 #define ROWS_PER_CYCLE 1 /*I think this needs to be 1 in anycase*/
133 /* the complete decompress function, not actually used in sparrow */
134 INVISIBLE void
135 decompress_buffer(struct jpeg_decompress_struct *cinfo, guint8* src, int size, guint8* dest,
136 int *width, int *height)
138 jpeg_create_decompress(cinfo);
139 jpeg_mem_src(cinfo, src, size);
141 jpeg_read_header(cinfo, TRUE);
142 jpeg_start_decompress(cinfo);
143 cinfo->out_color_space = COLOURSPACE;
145 *width = cinfo->output_width;
146 *height = cinfo->output_height;
148 /*use 4 here, not cinfo->num_channels, because libjpeg_turbo is doing the
149 RGBx colour space conversion */
150 int stride = 4 * cinfo->output_width;
151 guint8* row = dest;
152 while (cinfo->output_scanline < cinfo->output_height){
153 int read = jpeg_read_scanlines(cinfo, &row, ROWS_PER_CYCLE);
154 row += stride * read;
156 jpeg_finish_decompress(cinfo);
157 jpeg_destroy_decompress(cinfo);
163 INVISIBLE void
164 begin_reading_jpeg(GstSparrow *sparrow, guint8* src, int size){
165 struct jpeg_decompress_struct *cinfo = sparrow->cinfo;
166 GST_DEBUG("cinfo is %p, src %p, size %d\n", cinfo, src, size);
168 jpeg_create_decompress(cinfo);
169 jpeg_mem_src(cinfo, src, size);
171 jpeg_read_header(cinfo, TRUE);
172 jpeg_start_decompress(cinfo);
173 cinfo->out_color_space = sparrow->jpeg_colourspace;
174 if (cinfo->output_width != (guint)sparrow->out.width ||
175 cinfo->output_height != (guint)sparrow->out.height){
176 GST_ERROR("jpeg sizes are wrong! %dx%d, should be %dx%d.\n"
177 "Not doing anything: this is probably goodbye.\n",
178 cinfo->output_width, cinfo->output_height,
179 sparrow->out.width, sparrow->out.height);
184 INVISIBLE void
185 read_one_line(GstSparrow *sparrow, guint8* dest){
186 struct jpeg_decompress_struct *cinfo = sparrow->cinfo;
187 if (cinfo->output_scanline < cinfo->output_height){
188 jpeg_read_scanlines(cinfo, &dest, 1);
190 else {
191 GST_WARNING("wanted to read line %d of jpeg that thinks it is %d lines high!",
192 cinfo->output_scanline, cinfo->output_height);
196 INVISIBLE void
197 finish_reading_jpeg(GstSparrow *sparrow){
198 jpeg_finish_decompress(sparrow->cinfo);
199 jpeg_destroy_decompress(sparrow->cinfo);
203 INVISIBLE void
204 init_jpeg_src(GstSparrow *sparrow){
205 sparrow->cinfo = zalloc_or_die(sizeof(struct jpeg_decompress_struct));
206 struct jpeg_error_mgr *jerr = zalloc_or_die(sizeof(struct jpeg_error_mgr));
207 sparrow->cinfo->err = jpeg_std_error(jerr);
208 /*rshift is little-endian, jpg enums big-endian */
209 switch (sparrow->out.rshift){
210 case 0:
211 sparrow->jpeg_colourspace = JCS_EXT_RGBX;
212 break;
213 case 8:
214 sparrow->jpeg_colourspace = JCS_EXT_XRGB;
215 break;
216 case 16:
217 sparrow->jpeg_colourspace = JCS_EXT_BGRX;
218 break;
219 case 24:
220 sparrow->jpeg_colourspace = JCS_EXT_XBGR;
221 break;
222 default:
223 GST_WARNING("No discernable colorspace! rshift is %d", sparrow->out.rshift);
227 INVISIBLE void
228 finalise_jpeg_src(GstSparrow *sparrow){
229 jpeg_destroy_decompress(sparrow->cinfo);
230 free(sparrow->cinfo->err);
231 free(sparrow->cinfo);