OLD | NEW |
1 /* | 1 /* |
2 * jdatadst-tj.c | 2 * jdatadst-tj.c |
3 * | 3 * |
4 * This file was part of the Independent JPEG Group's software: | 4 * This file was part of the Independent JPEG Group's software: |
5 * Copyright (C) 1994-1996, Thomas G. Lane. | 5 * Copyright (C) 1994-1996, Thomas G. Lane. |
6 * Modified 2009-2012 by Guido Vollbeding. | 6 * Modified 2009-2012 by Guido Vollbeding. |
7 * libjpeg-turbo Modifications: | 7 * libjpeg-turbo Modifications: |
8 * Copyright (C) 2011, D. R. Commander. | 8 * Copyright (C) 2011, 2014 D. R. Commander. |
9 * For conditions of distribution and use, see the accompanying README file. | 9 * For conditions of distribution and use, see the accompanying README.ijg |
| 10 * file. |
10 * | 11 * |
11 * This file contains compression data destination routines for the case of | 12 * This file contains compression data destination routines for the case of |
12 * emitting JPEG data to memory or to a file (or any stdio stream). | 13 * emitting JPEG data to memory or to a file (or any stdio stream). |
13 * While these routines are sufficient for most applications, | 14 * While these routines are sufficient for most applications, |
14 * some will want to use a different destination manager. | 15 * some will want to use a different destination manager. |
15 * IMPORTANT: we assume that fwrite() will correctly transcribe an array of | 16 * IMPORTANT: we assume that fwrite() will correctly transcribe an array of |
16 * JOCTETs into 8-bit-wide elements on external storage. If char is wider | 17 * JOCTETs into 8-bit-wide elements on external storage. If char is wider |
17 * than 8 bits on your machine, you may need to do some tweaking. | 18 * than 8 bits on your machine, you may need to do some tweaking. |
18 */ | 19 */ |
19 | 20 |
20 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ | 21 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ |
21 #include "jinclude.h" | 22 #include "jinclude.h" |
22 #include "jpeglib.h" | 23 #include "jpeglib.h" |
23 #include "jerror.h" | 24 #include "jerror.h" |
24 | 25 |
25 #ifndef HAVE_STDLIB_H» » /* <stdlib.h> should declare malloc(),free() */ | 26 #ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */ |
26 extern void * malloc JPP((size_t size)); | 27 extern void *malloc (size_t size); |
27 extern void free JPP((void *ptr)); | 28 extern void free (void *ptr); |
28 #endif | 29 #endif |
29 | 30 |
30 | 31 |
31 #define OUTPUT_BUF_SIZE 4096» /* choose an efficiently fwrite'able size */ | 32 #define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ |
32 | 33 |
33 | 34 |
34 /* Expanded data destination object for memory output */ | 35 /* Expanded data destination object for memory output */ |
35 | 36 |
36 typedef struct { | 37 typedef struct { |
37 struct jpeg_destination_mgr pub; /* public fields */ | 38 struct jpeg_destination_mgr pub; /* public fields */ |
38 | 39 |
39 unsigned char ** outbuffer;» /* target buffer */ | 40 unsigned char **outbuffer; /* target buffer */ |
40 unsigned long * outsize; | 41 unsigned long *outsize; |
41 unsigned char * newbuffer;» /* newly allocated buffer */ | 42 unsigned char *newbuffer; /* newly allocated buffer */ |
42 JOCTET * buffer;» » /* start of buffer */ | 43 JOCTET *buffer; /* start of buffer */ |
43 size_t bufsize; | 44 size_t bufsize; |
44 boolean alloc; | 45 boolean alloc; |
45 } my_mem_destination_mgr; | 46 } my_mem_destination_mgr; |
46 | 47 |
47 typedef my_mem_destination_mgr * my_mem_dest_ptr; | 48 typedef my_mem_destination_mgr *my_mem_dest_ptr; |
48 | 49 |
49 | 50 |
50 /* | 51 /* |
51 * Initialize destination --- called by jpeg_start_compress | 52 * Initialize destination --- called by jpeg_start_compress |
52 * before any data is actually written. | 53 * before any data is actually written. |
53 */ | 54 */ |
54 | 55 |
55 METHODDEF(void) | 56 METHODDEF(void) |
56 init_mem_destination (j_compress_ptr cinfo) | 57 init_mem_destination (j_compress_ptr cinfo) |
57 { | 58 { |
(...skipping 21 matching lines...) Expand all Loading... |
79 * (typically the start of the current MCU). next_output_byte & free_in_buffer | 80 * (typically the start of the current MCU). next_output_byte & free_in_buffer |
80 * indicate where the restart point will be if the current call returns FALSE. | 81 * indicate where the restart point will be if the current call returns FALSE. |
81 * Data beyond this point will be regenerated after resumption, so do not | 82 * Data beyond this point will be regenerated after resumption, so do not |
82 * write it out when emptying the buffer externally. | 83 * write it out when emptying the buffer externally. |
83 */ | 84 */ |
84 | 85 |
85 METHODDEF(boolean) | 86 METHODDEF(boolean) |
86 empty_mem_output_buffer (j_compress_ptr cinfo) | 87 empty_mem_output_buffer (j_compress_ptr cinfo) |
87 { | 88 { |
88 size_t nextsize; | 89 size_t nextsize; |
89 JOCTET * nextbuffer; | 90 JOCTET *nextbuffer; |
90 my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest; | 91 my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest; |
91 | 92 |
92 if (!dest->alloc) ERREXIT(cinfo, JERR_BUFFER_SIZE); | 93 if (!dest->alloc) ERREXIT(cinfo, JERR_BUFFER_SIZE); |
93 | 94 |
94 /* Try to allocate new buffer with double size */ | 95 /* Try to allocate new buffer with double size */ |
95 nextsize = dest->bufsize * 2; | 96 nextsize = dest->bufsize * 2; |
96 nextbuffer = (JOCTET *) malloc(nextsize); | 97 nextbuffer = (JOCTET *) malloc(nextsize); |
97 | 98 |
98 if (nextbuffer == NULL) | 99 if (nextbuffer == NULL) |
99 ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); | 100 ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 * Otherwise, or when the actual data output exceeds the given size, | 141 * Otherwise, or when the actual data output exceeds the given size, |
141 * the library adapts the buffer size as necessary. | 142 * the library adapts the buffer size as necessary. |
142 * The standard library functions malloc/free are used for allocating | 143 * The standard library functions malloc/free are used for allocating |
143 * larger memory, so the buffer is available to the application after | 144 * larger memory, so the buffer is available to the application after |
144 * finishing compression, and then the application is responsible for | 145 * finishing compression, and then the application is responsible for |
145 * freeing the requested memory. | 146 * freeing the requested memory. |
146 */ | 147 */ |
147 | 148 |
148 GLOBAL(void) | 149 GLOBAL(void) |
149 jpeg_mem_dest_tj (j_compress_ptr cinfo, | 150 jpeg_mem_dest_tj (j_compress_ptr cinfo, |
150 » unsigned char ** outbuffer, unsigned long * outsize, | 151 unsigned char **outbuffer, unsigned long *outsize, |
151 » boolean alloc) | 152 boolean alloc) |
152 { | 153 { |
| 154 boolean reused = FALSE; |
153 my_mem_dest_ptr dest; | 155 my_mem_dest_ptr dest; |
154 | 156 |
155 if (outbuffer == NULL || outsize == NULL)» /* sanity check */ | 157 if (outbuffer == NULL || outsize == NULL) /* sanity check */ |
156 ERREXIT(cinfo, JERR_BUFFER_SIZE); | 158 ERREXIT(cinfo, JERR_BUFFER_SIZE); |
157 | 159 |
158 /* The destination object is made permanent so that multiple JPEG images | 160 /* The destination object is made permanent so that multiple JPEG images |
159 * can be written to the same buffer without re-executing jpeg_mem_dest. | 161 * can be written to the same buffer without re-executing jpeg_mem_dest. |
160 */ | 162 */ |
161 if (cinfo->dest == NULL) {» /* first time for this JPEG object? */ | 163 if (cinfo->dest == NULL) { /* first time for this JPEG object? */ |
162 cinfo->dest = (struct jpeg_destination_mgr *) | 164 cinfo->dest = (struct jpeg_destination_mgr *) |
163 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, | 165 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, |
164 » » » » SIZEOF(my_mem_destination_mgr)); | 166 sizeof(my_mem_destination_mgr)); |
165 dest = (my_mem_dest_ptr) cinfo->dest; | 167 dest = (my_mem_dest_ptr) cinfo->dest; |
166 dest->newbuffer = NULL; | 168 dest->newbuffer = NULL; |
| 169 dest->buffer = NULL; |
167 } | 170 } |
168 | 171 |
169 dest = (my_mem_dest_ptr) cinfo->dest; | 172 dest = (my_mem_dest_ptr) cinfo->dest; |
170 dest->pub.init_destination = init_mem_destination; | 173 dest->pub.init_destination = init_mem_destination; |
171 dest->pub.empty_output_buffer = empty_mem_output_buffer; | 174 dest->pub.empty_output_buffer = empty_mem_output_buffer; |
172 dest->pub.term_destination = term_mem_destination; | 175 dest->pub.term_destination = term_mem_destination; |
| 176 if (dest->buffer == *outbuffer && *outbuffer != NULL && alloc) |
| 177 reused = TRUE; |
173 dest->outbuffer = outbuffer; | 178 dest->outbuffer = outbuffer; |
174 dest->outsize = outsize; | 179 dest->outsize = outsize; |
175 dest->alloc = alloc; | 180 dest->alloc = alloc; |
176 | 181 |
177 if (*outbuffer == NULL || *outsize == 0) { | 182 if (*outbuffer == NULL || *outsize == 0) { |
178 if (alloc) { | 183 if (alloc) { |
179 /* Allocate initial buffer */ | 184 /* Allocate initial buffer */ |
180 dest->newbuffer = *outbuffer = (unsigned char *) malloc(OUTPUT_BUF_SIZE); | 185 dest->newbuffer = *outbuffer = (unsigned char *) malloc(OUTPUT_BUF_SIZE); |
181 if (dest->newbuffer == NULL) | 186 if (dest->newbuffer == NULL) |
182 ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); | 187 ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); |
183 *outsize = OUTPUT_BUF_SIZE; | 188 *outsize = OUTPUT_BUF_SIZE; |
184 } | 189 } |
185 else ERREXIT(cinfo, JERR_BUFFER_SIZE); | 190 else ERREXIT(cinfo, JERR_BUFFER_SIZE); |
186 } | 191 } |
187 | 192 |
188 dest->pub.next_output_byte = dest->buffer = *outbuffer; | 193 dest->pub.next_output_byte = dest->buffer = *outbuffer; |
189 dest->pub.free_in_buffer = dest->bufsize = *outsize; | 194 if (!reused) |
| 195 dest->bufsize = *outsize; |
| 196 dest->pub.free_in_buffer = dest->bufsize; |
190 } | 197 } |
OLD | NEW |