@@ -204,6 +204,157 @@ void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height
204
204
/* And we're done! */
205
205
}
206
206
207
+ #ifdef JK2_MODE
208
+ void LoadJPGFromBuffer ( byte *inputBuffer, size_t len, unsigned char **pic, int *width, int *height ) {
209
+ /* This struct contains the JPEG decompression parameters and pointers to
210
+ * working space (which is allocated as needed by the JPEG library).
211
+ */
212
+ struct jpeg_decompress_struct cinfo = { NULL };
213
+ /* We use our private extension JPEG error handler.
214
+ * Note that this struct must live as long as the main JPEG parameter
215
+ * struct, to avoid dangling-pointer problems.
216
+ */
217
+ /* This struct represents a JPEG error handler. It is declared separately
218
+ * because applications often want to supply a specialized error handler
219
+ * (see the second half of this file for an example). But here we just
220
+ * take the easy way out and use the standard error handler, which will
221
+ * print a message on stderr and call exit() if compression fails.
222
+ * Note that this struct must live as long as the main JPEG parameter
223
+ * struct, to avoid dangling-pointer problems.
224
+ */
225
+ struct jpeg_error_mgr jerr;
226
+ /* More stuff */
227
+ JSAMPARRAY buffer; /* Output row buffer */
228
+ unsigned int row_stride; /* physical row width in output buffer */
229
+ unsigned int pixelcount, memcount;
230
+ unsigned int sindex, dindex;
231
+ byte *out;
232
+ byte *buf;
233
+
234
+ if (!inputBuffer) {
235
+ return ;
236
+ }
237
+
238
+ /* Step 1: allocate and initialize JPEG decompression object */
239
+
240
+ /* We have to set up the error handler first, in case the initialization
241
+ * step fails. (Unlikely, but it could happen if you are out of memory.)
242
+ * This routine fills in the contents of struct jerr, and returns jerr's
243
+ * address which we place into the link field in cinfo.
244
+ */
245
+ cinfo.err = jpeg_std_error (&jerr);
246
+ cinfo.err ->error_exit = R_JPGErrorExit;
247
+ cinfo.err ->output_message = R_JPGOutputMessage;
248
+
249
+ /* Now we can initialize the JPEG decompression object. */
250
+ jpeg_create_decompress (&cinfo);
251
+
252
+ /* Step 2: specify data source (eg, a file) */
253
+
254
+ jpeg_mem_src (&cinfo, inputBuffer, len);
255
+
256
+ /* Step 3: read file parameters with jpeg_read_header() */
257
+
258
+ (void ) jpeg_read_header (&cinfo, TRUE );
259
+ /* We can ignore the return value from jpeg_read_header since
260
+ * (a) suspension is not possible with the stdio data source, and
261
+ * (b) we passed TRUE to reject a tables-only JPEG file as an error.
262
+ * See libjpeg.doc for more info.
263
+ */
264
+
265
+ /* Step 4: set parameters for decompression */
266
+
267
+
268
+ /* Make sure it always converts images to RGB color space. This will
269
+ * automatically convert 8-bit greyscale images to RGB as well. */
270
+ cinfo.out_color_space = JCS_RGB;
271
+
272
+ /* Step 5: Start decompressor */
273
+
274
+ (void ) jpeg_start_decompress (&cinfo);
275
+ /* We can ignore the return value since suspension is not possible
276
+ * with the stdio data source.
277
+ */
278
+
279
+ /* We may need to do some setup of our own at this point before reading
280
+ * the data. After jpeg_start_decompress() we have the correct scaled
281
+ * output image dimensions available, as well as the output colormap
282
+ * if we asked for color quantization.
283
+ * In this example, we need to make an output work buffer of the right size.
284
+ */
285
+ /* JSAMPLEs per row in output buffer */
286
+ pixelcount = cinfo.output_width * cinfo.output_height ;
287
+
288
+ if (!cinfo.output_width || !cinfo.output_height
289
+ || ((pixelcount * 4 ) / cinfo.output_width ) / 4 != cinfo.output_height
290
+ || pixelcount > 0x1FFFFFFF || cinfo.output_components != 3
291
+ )
292
+ {
293
+ // Free the memory to make sure we don't leak memory
294
+ jpeg_destroy_decompress (&cinfo);
295
+
296
+ ri.Printf ( PRINT_ALL, " LoadJPG: invalid image format: %dx%d*4=%d, components: %d" ,
297
+ cinfo.output_width , cinfo.output_height , pixelcount * 4 , cinfo.output_components );
298
+ return ;
299
+ }
300
+
301
+ memcount = pixelcount * 4 ;
302
+ row_stride = cinfo.output_width * cinfo.output_components ;
303
+
304
+ out = (byte *)Z_Malloc (memcount, TAG_TEMP_WORKSPACE, qfalse);
305
+
306
+ *width = cinfo.output_width ;
307
+ *height = cinfo.output_height ;
308
+
309
+ /* Step 6: while (scan lines remain to be read) */
310
+ /* jpeg_read_scanlines(...); */
311
+
312
+ /* Here we use the library's state variable cinfo.output_scanline as the
313
+ * loop counter, so that we don't have to keep track ourselves.
314
+ */
315
+ while (cinfo.output_scanline < cinfo.output_height ) {
316
+ /* jpeg_read_scanlines expects an array of pointers to scanlines.
317
+ * Here the array is only one element long, but you could ask for
318
+ * more than one scanline at a time if that's more convenient.
319
+ */
320
+ buf = ((out+(row_stride*cinfo.output_scanline )));
321
+ buffer = &buf;
322
+ (void ) jpeg_read_scanlines (&cinfo, buffer, 1 );
323
+ }
324
+
325
+ buf = out;
326
+ // Expand from RGB to RGBA
327
+ sindex = pixelcount * cinfo.output_components ;
328
+ dindex = memcount;
329
+
330
+ do {
331
+ buf[--dindex] = 255 ;
332
+ buf[--dindex] = buf[--sindex];
333
+ buf[--dindex] = buf[--sindex];
334
+ buf[--dindex] = buf[--sindex];
335
+ } while (sindex);
336
+
337
+ *pic = out;
338
+
339
+ /* Step 7: Finish decompression */
340
+
341
+ (void ) jpeg_finish_decompress (&cinfo);
342
+ /* We can ignore the return value since suspension is not possible
343
+ * with the stdio data source.
344
+ */
345
+
346
+ /* Step 8: Release JPEG decompression object */
347
+
348
+ /* This is an important step since it will release a good deal of memory. */
349
+ jpeg_destroy_decompress (&cinfo);
350
+
351
+ /* At this point you may want to check to see whether any corrupt-data
352
+ * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
353
+ */
354
+
355
+ /* And we're done! */
356
+ }
357
+ #endif
207
358
208
359
/* Expanded data destination object for stdio output */
209
360
0 commit comments