| File: | root/firefox-clang/media/libjpeg/src/jdatadst.c |
| Warning: | line 134, column 3 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * jdatadst.c | |||
| 3 | * | |||
| 4 | * This file was part of the Independent JPEG Group's software: | |||
| 5 | * Copyright (C) 1994-1996, Thomas G. Lane. | |||
| 6 | * Modified 2009-2012 by Guido Vollbeding. | |||
| 7 | * libjpeg-turbo Modifications: | |||
| 8 | * Copyright (C) 2013, 2016, 2022, D. R. Commander. | |||
| 9 | * For conditions of distribution and use, see the accompanying README.ijg | |||
| 10 | * file. | |||
| 11 | * | |||
| 12 | * This file contains compression data destination routines for the case of | |||
| 13 | * emitting JPEG data to memory or to a file (or any stdio stream). | |||
| 14 | * While these routines are sufficient for most applications, | |||
| 15 | * some will want to use a different destination manager. | |||
| 16 | * IMPORTANT: we assume that fwrite() will correctly transcribe an array of | |||
| 17 | * JOCTETs into 8-bit-wide elements on external storage. If char is wider | |||
| 18 | * than 8 bits on your machine, you may need to do some tweaking. | |||
| 19 | */ | |||
| 20 | ||||
| 21 | /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ | |||
| 22 | #include "jinclude.h" | |||
| 23 | #include "jpeglib.h" | |||
| 24 | #include "jerror.h" | |||
| 25 | ||||
| 26 | ||||
| 27 | /* Expanded data destination object for stdio output */ | |||
| 28 | ||||
| 29 | typedef struct { | |||
| 30 | struct jpeg_destination_mgr pub; /* public fields */ | |||
| 31 | ||||
| 32 | FILE *outfile; /* target stream */ | |||
| 33 | JOCTET *buffer; /* start of buffer */ | |||
| 34 | } my_destination_mgr; | |||
| 35 | ||||
| 36 | typedef my_destination_mgr *my_dest_ptr; | |||
| 37 | ||||
| 38 | #define OUTPUT_BUF_SIZE4096 4096 /* choose an efficiently fwrite'able size */ | |||
| 39 | ||||
| 40 | ||||
| 41 | /* Expanded data destination object for memory output */ | |||
| 42 | ||||
| 43 | typedef struct { | |||
| 44 | struct jpeg_destination_mgr pub; /* public fields */ | |||
| 45 | ||||
| 46 | unsigned char **outbuffer; /* target buffer */ | |||
| 47 | unsigned long *outsize; | |||
| 48 | unsigned char *newbuffer; /* newly allocated buffer */ | |||
| 49 | JOCTET *buffer; /* start of buffer */ | |||
| 50 | size_t bufsize; | |||
| 51 | } my_mem_destination_mgr; | |||
| 52 | ||||
| 53 | typedef my_mem_destination_mgr *my_mem_dest_ptr; | |||
| 54 | ||||
| 55 | ||||
| 56 | /* | |||
| 57 | * Initialize destination --- called by jpeg_start_compress | |||
| 58 | * before any data is actually written. | |||
| 59 | */ | |||
| 60 | ||||
| 61 | METHODDEF(void)static void | |||
| 62 | init_destination(j_compress_ptr cinfo) | |||
| 63 | { | |||
| 64 | my_dest_ptr dest = (my_dest_ptr)cinfo->dest; | |||
| 65 | ||||
| 66 | /* Allocate the output buffer --- it will be released when done with image */ | |||
| 67 | dest->buffer = (JOCTET *) | |||
| 68 | (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE1, | |||
| 69 | OUTPUT_BUF_SIZE4096 * sizeof(JOCTET)); | |||
| 70 | ||||
| 71 | dest->pub.next_output_byte = dest->buffer; | |||
| 72 | dest->pub.free_in_buffer = OUTPUT_BUF_SIZE4096; | |||
| 73 | } | |||
| 74 | ||||
| 75 | METHODDEF(void)static void | |||
| 76 | init_mem_destination(j_compress_ptr cinfo) | |||
| 77 | { | |||
| 78 | /* no work necessary here */ | |||
| 79 | } | |||
| 80 | ||||
| 81 | ||||
| 82 | /* | |||
| 83 | * Empty the output buffer --- called whenever buffer fills up. | |||
| 84 | * | |||
| 85 | * In typical applications, this should write the entire output buffer | |||
| 86 | * (ignoring the current state of next_output_byte & free_in_buffer), | |||
| 87 | * reset the pointer & count to the start of the buffer, and return TRUE | |||
| 88 | * indicating that the buffer has been dumped. | |||
| 89 | * | |||
| 90 | * In applications that need to be able to suspend compression due to output | |||
| 91 | * overrun, a FALSE return indicates that the buffer cannot be emptied now. | |||
| 92 | * In this situation, the compressor will return to its caller (possibly with | |||
| 93 | * an indication that it has not accepted all the supplied scanlines). The | |||
| 94 | * application should resume compression after it has made more room in the | |||
| 95 | * output buffer. Note that there are substantial restrictions on the use of | |||
| 96 | * suspension --- see the documentation. | |||
| 97 | * | |||
| 98 | * When suspending, the compressor will back up to a convenient restart point | |||
| 99 | * (typically the start of the current MCU). next_output_byte & free_in_buffer | |||
| 100 | * indicate where the restart point will be if the current call returns FALSE. | |||
| 101 | * Data beyond this point will be regenerated after resumption, so do not | |||
| 102 | * write it out when emptying the buffer externally. | |||
| 103 | */ | |||
| 104 | ||||
| 105 | METHODDEF(boolean)static boolean | |||
| 106 | empty_output_buffer(j_compress_ptr cinfo) | |||
| 107 | { | |||
| 108 | my_dest_ptr dest = (my_dest_ptr)cinfo->dest; | |||
| 109 | ||||
| 110 | if (fwrite(dest->buffer, 1, OUTPUT_BUF_SIZE4096, dest->outfile) != | |||
| 111 | (size_t)OUTPUT_BUF_SIZE4096) | |||
| 112 | ERREXIT(cinfo, JERR_FILE_WRITE)((cinfo)->err->msg_code = (JERR_FILE_WRITE), (*(cinfo)-> err->error_exit) ((j_common_ptr)(cinfo))); | |||
| 113 | ||||
| 114 | dest->pub.next_output_byte = dest->buffer; | |||
| 115 | dest->pub.free_in_buffer = OUTPUT_BUF_SIZE4096; | |||
| 116 | ||||
| 117 | return TRUE1; | |||
| 118 | } | |||
| 119 | ||||
| 120 | METHODDEF(boolean)static boolean | |||
| 121 | empty_mem_output_buffer(j_compress_ptr cinfo) | |||
| 122 | { | |||
| 123 | size_t nextsize; | |||
| 124 | JOCTET *nextbuffer; | |||
| 125 | my_mem_dest_ptr dest = (my_mem_dest_ptr)cinfo->dest; | |||
| 126 | ||||
| 127 | /* Try to allocate new buffer with double size */ | |||
| 128 | nextsize = dest->bufsize * 2; | |||
| 129 | nextbuffer = (JOCTET *)malloc(nextsize); | |||
| ||||
| 130 | ||||
| 131 | if (nextbuffer == NULL((void*)0)) | |||
| 132 | ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10)((cinfo)->err->msg_code = (JERR_OUT_OF_MEMORY), (cinfo) ->err->msg_parm.i[0] = (10), (*(cinfo)->err->error_exit ) ((j_common_ptr)(cinfo))); | |||
| 133 | ||||
| 134 | memcpy(nextbuffer, dest->buffer, dest->bufsize); | |||
| ||||
| 135 | ||||
| 136 | free(dest->newbuffer); | |||
| 137 | ||||
| 138 | dest->newbuffer = nextbuffer; | |||
| 139 | ||||
| 140 | dest->pub.next_output_byte = nextbuffer + dest->bufsize; | |||
| 141 | dest->pub.free_in_buffer = dest->bufsize; | |||
| 142 | ||||
| 143 | dest->buffer = nextbuffer; | |||
| 144 | dest->bufsize = nextsize; | |||
| 145 | ||||
| 146 | return TRUE1; | |||
| 147 | } | |||
| 148 | ||||
| 149 | ||||
| 150 | /* | |||
| 151 | * Terminate destination --- called by jpeg_finish_compress | |||
| 152 | * after all data has been written. Usually needs to flush buffer. | |||
| 153 | * | |||
| 154 | * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding | |||
| 155 | * application must deal with any cleanup that should happen even | |||
| 156 | * for error exit. | |||
| 157 | */ | |||
| 158 | ||||
| 159 | METHODDEF(void)static void | |||
| 160 | term_destination(j_compress_ptr cinfo) | |||
| 161 | { | |||
| 162 | my_dest_ptr dest = (my_dest_ptr)cinfo->dest; | |||
| 163 | size_t datacount = OUTPUT_BUF_SIZE4096 - dest->pub.free_in_buffer; | |||
| 164 | ||||
| 165 | /* Write any data remaining in the buffer */ | |||
| 166 | if (datacount > 0) { | |||
| 167 | if (fwrite(dest->buffer, 1, datacount, dest->outfile) != datacount) | |||
| 168 | ERREXIT(cinfo, JERR_FILE_WRITE)((cinfo)->err->msg_code = (JERR_FILE_WRITE), (*(cinfo)-> err->error_exit) ((j_common_ptr)(cinfo))); | |||
| 169 | } | |||
| 170 | fflush(dest->outfile); | |||
| 171 | /* Make sure we wrote the output file OK */ | |||
| 172 | if (ferror(dest->outfile)) | |||
| 173 | ERREXIT(cinfo, JERR_FILE_WRITE)((cinfo)->err->msg_code = (JERR_FILE_WRITE), (*(cinfo)-> err->error_exit) ((j_common_ptr)(cinfo))); | |||
| 174 | } | |||
| 175 | ||||
| 176 | METHODDEF(void)static void | |||
| 177 | term_mem_destination(j_compress_ptr cinfo) | |||
| 178 | { | |||
| 179 | my_mem_dest_ptr dest = (my_mem_dest_ptr)cinfo->dest; | |||
| 180 | ||||
| 181 | *dest->outbuffer = dest->buffer; | |||
| 182 | *dest->outsize = (unsigned long)(dest->bufsize - dest->pub.free_in_buffer); | |||
| 183 | } | |||
| 184 | ||||
| 185 | ||||
| 186 | /* | |||
| 187 | * Prepare for output to a stdio stream. | |||
| 188 | * The caller must have already opened the stream, and is responsible | |||
| 189 | * for closing it after finishing compression. | |||
| 190 | */ | |||
| 191 | ||||
| 192 | GLOBAL(void)void | |||
| 193 | jpeg_stdio_dest(j_compress_ptr cinfo, FILE *outfile) | |||
| 194 | { | |||
| 195 | my_dest_ptr dest; | |||
| 196 | ||||
| 197 | /* The destination object is made permanent so that multiple JPEG images | |||
| 198 | * can be written to the same file without re-executing jpeg_stdio_dest. | |||
| 199 | */ | |||
| 200 | if (cinfo->dest == NULL((void*)0)) { /* first time for this JPEG object? */ | |||
| 201 | cinfo->dest = (struct jpeg_destination_mgr *) | |||
| 202 | (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT0, | |||
| 203 | sizeof(my_destination_mgr)); | |||
| 204 | } else if (cinfo->dest->init_destination != init_destination) { | |||
| 205 | /* It is unsafe to reuse the existing destination manager unless it was | |||
| 206 | * created by this function. Otherwise, there is no guarantee that the | |||
| 207 | * opaque structure is the right size. Note that we could just create a | |||
| 208 | * new structure, but the old structure would not be freed until | |||
| 209 | * jpeg_destroy_compress() was called. | |||
| 210 | */ | |||
| 211 | ERREXIT(cinfo, JERR_BUFFER_SIZE)((cinfo)->err->msg_code = (JERR_BUFFER_SIZE), (*(cinfo) ->err->error_exit) ((j_common_ptr)(cinfo))); | |||
| 212 | } | |||
| 213 | ||||
| 214 | dest = (my_dest_ptr)cinfo->dest; | |||
| 215 | dest->pub.init_destination = init_destination; | |||
| 216 | dest->pub.empty_output_buffer = empty_output_buffer; | |||
| 217 | dest->pub.term_destination = term_destination; | |||
| 218 | dest->outfile = outfile; | |||
| 219 | } | |||
| 220 | ||||
| 221 | ||||
| 222 | /* | |||
| 223 | * Prepare for output to a memory buffer. | |||
| 224 | * The caller may supply an own initial buffer with appropriate size. | |||
| 225 | * Otherwise, or when the actual data output exceeds the given size, | |||
| 226 | * the library adapts the buffer size as necessary. | |||
| 227 | * The standard library functions malloc/free are used for allocating | |||
| 228 | * larger memory, so the buffer is available to the application after | |||
| 229 | * finishing compression, and then the application is responsible for | |||
| 230 | * freeing the requested memory. | |||
| 231 | * Note: An initial buffer supplied by the caller is expected to be | |||
| 232 | * managed by the application. The library does not free such buffer | |||
| 233 | * when allocating a larger buffer. | |||
| 234 | */ | |||
| 235 | ||||
| 236 | GLOBAL(void)void | |||
| 237 | jpeg_mem_dest(j_compress_ptr cinfo, unsigned char **outbuffer, | |||
| 238 | unsigned long *outsize) | |||
| 239 | { | |||
| 240 | my_mem_dest_ptr dest; | |||
| 241 | ||||
| 242 | if (outbuffer == NULL((void*)0) || outsize == NULL((void*)0)) /* sanity check */ | |||
| 243 | ERREXIT(cinfo, JERR_BUFFER_SIZE)((cinfo)->err->msg_code = (JERR_BUFFER_SIZE), (*(cinfo) ->err->error_exit) ((j_common_ptr)(cinfo))); | |||
| 244 | ||||
| 245 | /* The destination object is made permanent so that multiple JPEG images | |||
| 246 | * can be written to the same buffer without re-executing jpeg_mem_dest. | |||
| 247 | */ | |||
| 248 | if (cinfo->dest == NULL((void*)0)) { /* first time for this JPEG object? */ | |||
| 249 | cinfo->dest = (struct jpeg_destination_mgr *) | |||
| 250 | (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT0, | |||
| 251 | sizeof(my_mem_destination_mgr)); | |||
| 252 | } else if (cinfo->dest->init_destination != init_mem_destination) { | |||
| 253 | /* It is unsafe to reuse the existing destination manager unless it was | |||
| 254 | * created by this function. | |||
| 255 | */ | |||
| 256 | ERREXIT(cinfo, JERR_BUFFER_SIZE)((cinfo)->err->msg_code = (JERR_BUFFER_SIZE), (*(cinfo) ->err->error_exit) ((j_common_ptr)(cinfo))); | |||
| 257 | } | |||
| 258 | ||||
| 259 | dest = (my_mem_dest_ptr)cinfo->dest; | |||
| 260 | dest->pub.init_destination = init_mem_destination; | |||
| 261 | dest->pub.empty_output_buffer = empty_mem_output_buffer; | |||
| 262 | dest->pub.term_destination = term_mem_destination; | |||
| 263 | dest->outbuffer = outbuffer; | |||
| 264 | dest->outsize = outsize; | |||
| 265 | dest->newbuffer = NULL((void*)0); | |||
| 266 | ||||
| 267 | if (*outbuffer == NULL((void*)0) || *outsize == 0) { | |||
| 268 | /* Allocate initial buffer */ | |||
| 269 | dest->newbuffer = *outbuffer = (unsigned char *)malloc(OUTPUT_BUF_SIZE4096); | |||
| 270 | if (dest->newbuffer == NULL((void*)0)) | |||
| 271 | ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10)((cinfo)->err->msg_code = (JERR_OUT_OF_MEMORY), (cinfo) ->err->msg_parm.i[0] = (10), (*(cinfo)->err->error_exit ) ((j_common_ptr)(cinfo))); | |||
| 272 | *outsize = OUTPUT_BUF_SIZE4096; | |||
| 273 | } | |||
| 274 | ||||
| 275 | dest->pub.next_output_byte = dest->buffer = *outbuffer; | |||
| 276 | dest->pub.free_in_buffer = dest->bufsize = *outsize; | |||
| 277 | } |