2 * This library is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published
4 * by the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This library is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 #include "bccmodels.h"
79 #define QUICKTIME_MARKER_SIZE 0x2c
80 #define AVI_MARKER_SIZE 0x12
81 #define QUICKTIME_JPEG_TAG 0x6d6a7067
82 #define QUICKTIME_AVI_TAG 0x41564931
85 METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo)
87 /* cinfo->err really points to a mjpeg_error_mgr struct, so coerce pointer */
88 mjpeg_error_ptr mjpegerr = (mjpeg_error_ptr) cinfo->err;
90 /* Always display the message. */
91 /* We could postpone this until after returning, if we chose. */
92 (*cinfo->err->output_message) (cinfo);
94 /* Return control to the setjmp point */
95 longjmp(mjpegerr->setjmp_buffer, 1);
100 struct jpeg_destination_mgr pub; /* public fields */
102 JOCTET *buffer; /* Pointer to buffer */
103 mjpeg_compressor *engine;
104 } mjpeg_destination_mgr;
106 typedef mjpeg_destination_mgr *mjpeg_dest_ptr;
110 * Initialize destination --- called by jpeg_start_compress
111 * before any data is actually written.
114 METHODDEF(void) init_destination(j_compress_ptr cinfo)
116 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
118 /* Set the pointer to the preallocated buffer */
119 if(!dest->engine->output_buffer)
121 dest->engine->output_buffer = new unsigned char[65536];
122 memset(dest->engine->output_buffer,0,65536);
123 dest->engine->output_allocated = 65536;
125 dest->buffer = dest->engine->output_buffer;
126 dest->pub.next_output_byte = dest->engine->output_buffer;
127 dest->pub.free_in_buffer = dest->engine->output_allocated;
131 * Empty the output buffer --- called whenever buffer fills up.
133 * In typical applications, this should write the entire output buffer
134 * (ignoring the current state of next_output_byte & free_in_buffer),
135 * reset the pointer & count to the start of the buffer, and return TRUE
136 * indicating that the buffer has been dumped.
138 * In applications that need to be able to suspend compression due to output
139 * overrun, a FALSE return indicates that the buffer cannot be emptied now.
140 * In this situation, the compressor will return to its caller (possibly with
141 * an indication that it has not accepted all the supplied scanlines). The
142 * application should resume compression after it has made more room in the
143 * output buffer. Note that there are substantial restrictions on the use of
144 * suspension --- see the documentation.
146 * When suspending, the compressor will back up to a convenient restart point
147 * (typically the start of the current MCU). next_output_byte & free_in_buffer
148 * indicate where the restart point will be if the current call returns FALSE.
149 * Data beyond this point will be regenerated after resumption, so do not
150 * write it out when emptying the buffer externally.
153 METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
155 /* Allocate a bigger buffer. */
156 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
158 dest->engine->output_size = dest->engine->output_allocated;
159 dest->engine->output_allocated *= 2;
160 unsigned char *new_buffer = new unsigned char[dest->engine->output_allocated];
161 memcpy(new_buffer, dest->engine->output_buffer, dest->engine->output_size);
162 delete [] dest->engine->output_buffer;
163 dest->engine->output_buffer = new_buffer;
164 dest->buffer = dest->engine->output_buffer;
165 dest->pub.next_output_byte = dest->buffer + dest->engine->output_size;
166 dest->pub.free_in_buffer = dest->engine->output_allocated - dest->engine->output_size;
172 * Terminate destination --- called by jpeg_finish_compress
173 * after all data has been written. Usually needs to flush buffer.
175 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
176 * application must deal with any cleanup that should happen even
179 METHODDEF(void) term_destination(j_compress_ptr cinfo)
181 /* Just get the length */
182 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
183 dest->engine->output_size = dest->engine->output_allocated - dest->pub.free_in_buffer;
186 GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo, mjpeg_compressor *engine)
190 /* The destination object is made permanent so that multiple JPEG images
191 * can be written to the same file without re-executing jpeg_stdio_dest.
192 * This makes it dangerous to use this manager and a different destination
193 * manager serially with the same JPEG object, because their private object
194 * sizes may be different. Caveat programmer.
196 if(cinfo->dest == NULL)
198 /* first time for this JPEG object? */
199 cinfo->dest = (struct jpeg_destination_mgr *)
200 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
202 sizeof(mjpeg_destination_mgr));
205 dest = (mjpeg_dest_ptr)cinfo->dest;
206 dest->pub.init_destination = init_destination;
207 dest->pub.empty_output_buffer = empty_output_buffer;
208 dest->pub.term_destination = term_destination;
209 dest->engine = engine;
226 struct jpeg_source_mgr pub; /* public fields */
228 JOCTET * buffer; /* start of buffer */
229 int bytes; /* total size of buffer */
232 typedef mjpeg_source_mgr* mjpeg_src_ptr;
234 METHODDEF(void) init_source(j_decompress_ptr cinfo)
236 //mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
239 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo)
241 mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
243 src->buffer[0] = (JOCTET)0xFF;
244 src->buffer[1] = (JOCTET)M_EOI;
245 src->pub.next_input_byte = src->buffer;
246 src->pub.bytes_in_buffer = 2;
252 METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes)
254 mjpeg_src_ptr src = (mjpeg_src_ptr)cinfo->src;
256 src->pub.next_input_byte += (size_t)num_bytes;
257 src->pub.bytes_in_buffer -= (size_t)num_bytes;
261 METHODDEF(void) term_source(j_decompress_ptr cinfo)
265 GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long bytes)
269 /* first time for this JPEG object? */
270 if(cinfo->src == NULL)
272 cinfo->src = (struct jpeg_source_mgr*)
273 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
275 sizeof(mjpeg_source_mgr));
276 src = (mjpeg_src_ptr)cinfo->src;
279 src = (mjpeg_src_ptr)cinfo->src;
280 src->pub.init_source = init_source;
281 src->pub.fill_input_buffer = fill_input_buffer;
282 src->pub.skip_input_data = skip_input_data;
283 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
284 src->pub.term_source = term_source;
285 src->pub.bytes_in_buffer = bytes;
286 src->pub.next_input_byte = buffer;
287 src->buffer = buffer;
291 /* JPEG DHT Segment for YCrCb omitted from MJPEG data */
293 unsigned char jpeg_odml_dht[0x1a4] = {
294 0xff, 0xc4, 0x01, 0xa2,
296 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
299 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
302 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
303 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
304 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
305 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
306 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
307 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
308 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
309 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
310 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
311 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
312 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
315 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
316 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
317 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
318 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
319 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
320 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
321 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
322 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
323 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
324 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
325 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
331 * Parse the DHT table.
332 * This code comes from jpeg6b (jdmarker.c).
335 int jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
336 JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
338 unsigned int length = (dht[2] << 8) + dht[3] - 2;
339 unsigned int pos = 4;
340 unsigned int count, i;
344 unsigned char bits[17];
345 unsigned char huffval[256];
352 for (i = 1; i <= 16; ++i)
354 bits[i] = dht[pos++];
359 if (count > 256 || count > length)
362 for (i = 0; i < count; ++i)
363 huffval[i] = dht[pos++];
369 hufftbl = &ac_tables[index];
372 hufftbl = &dc_tables[index];
374 if (index < 0 || index >= NUM_HUFF_TBLS)
377 if (*hufftbl == NULL)
378 *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
379 if (*hufftbl == NULL)
382 memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
383 memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
406 static void reset_buffer(unsigned char **buffer, long *size, long *allocated)
411 static void delete_buffer(unsigned char **buffer, long *size, long *allocated)
421 static void append_buffer(unsigned char **buffer,
429 *buffer = new unsigned char[65536];
430 memset(*buffer,0,65536);
435 if(*size + data_size + 0x100 > *allocated)
437 *allocated = *size + data_size + 0x100;
438 unsigned char *new_buffer = new unsigned char[*allocated];
439 memcpy(new_buffer, *buffer, *size);
441 *buffer = new_buffer;
444 memcpy(*buffer + *size, data, data_size);
448 static void allocate_temps(mjpeg_t *mjpeg)
452 if(!mjpeg->temp_data)
454 switch(mjpeg->jpeg_color_model)
457 //printf("allocate_temps 1\n");
458 mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 2];
459 mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
460 mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
461 mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
462 for(i = 0; i < mjpeg->coded_h; i++)
464 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
465 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w / 2;
466 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w / 2 * mjpeg->coded_h + i * mjpeg->coded_w / 2;
471 mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h * 3];
472 mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
473 mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h];
474 mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h];
477 memset(mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h,
479 mjpeg->coded_w * mjpeg->coded_h * 2);
481 for(i = 0; i < mjpeg->coded_h; i++)
483 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
484 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
485 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
490 mjpeg->temp_data = new unsigned char[mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h / 2];
491 mjpeg->temp_rows[0] = new unsigned char*[mjpeg->coded_h];
492 mjpeg->temp_rows[1] = new unsigned char*[mjpeg->coded_h / 2];
493 mjpeg->temp_rows[2] = new unsigned char*[mjpeg->coded_h / 2];
494 for(i = 0; i < mjpeg->coded_h; i++)
496 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
497 if(i < mjpeg->coded_h / 2)
499 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * (mjpeg->coded_w / 2);
500 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + (mjpeg->coded_h / 2) * (mjpeg->coded_w / 2) + i * (mjpeg->coded_w / 2);
508 static int get_input_row(mjpeg_t *mjpeg, mjpeg_compressor *compressor, int i)
511 if(mjpeg->fields > 1)
512 input_row = i * 2 + compressor->instance;
515 if(input_row >= mjpeg->coded_h) input_row = mjpeg->coded_h - 1;
519 // Get pointers to rows for the JPEG compressor
520 static void get_rows(mjpeg_t *mjpeg, mjpeg_compressor *compressor)
523 switch(mjpeg->jpeg_color_model)
527 if(!compressor->rows[0])
529 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
530 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
531 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
534 // User colormodel matches jpeg colormodel
535 if(mjpeg->color_model == BC_YUV444P &&
536 mjpeg->output_w == mjpeg->coded_w &&
537 mjpeg->output_h == mjpeg->coded_h)
539 for(i = 0; i < compressor->coded_field_h; i++)
541 int input_row = get_input_row(mjpeg, compressor, i);
542 compressor->rows[0][i] = mjpeg->y_argument +
543 mjpeg->coded_w * input_row;
544 compressor->rows[1][i] = mjpeg->u_argument +
545 mjpeg->coded_w * input_row;
546 compressor->rows[2][i] = mjpeg->v_argument +
547 mjpeg->coded_w * input_row;
552 for(i = 0; i < compressor->coded_field_h; i++)
554 int input_row = get_input_row(mjpeg, compressor, i);
555 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
556 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
557 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
565 if(!compressor->rows[0])
567 compressor->rows[0] = new unsigned char*[compressor->coded_field_h];
568 compressor->rows[1] = new unsigned char*[compressor->coded_field_h];
569 compressor->rows[2] = new unsigned char*[compressor->coded_field_h];
572 // User colormodel matches jpeg colormodel
573 if(mjpeg->color_model == BC_YUV422P &&
574 mjpeg->output_w == mjpeg->coded_w &&
575 mjpeg->output_h == mjpeg->coded_h)
577 for(i = 0; i < compressor->coded_field_h; i++)
579 int input_row = get_input_row(mjpeg, compressor, i);
580 compressor->rows[0][i] = mjpeg->y_argument +
581 mjpeg->coded_w * input_row;
582 compressor->rows[1][i] = mjpeg->u_argument +
583 (mjpeg->coded_w / 2) * input_row;
584 compressor->rows[2][i] = mjpeg->v_argument +
585 (mjpeg->coded_w / 2) * input_row;
590 for(i = 0; i < compressor->coded_field_h; i++)
592 int input_row = get_input_row(mjpeg, compressor, i);
593 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
594 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
595 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
603 if(!compressor->rows[0])
605 compressor->rows[0] = new unsigned char*[mjpeg->coded_h];
606 compressor->rows[1] = new unsigned char*[mjpeg->coded_h / 2];
607 compressor->rows[2] = new unsigned char*[mjpeg->coded_h / 2];
610 // User colormodel matches jpeg colormodel
611 if(mjpeg->color_model == BC_YUV420P &&
612 mjpeg->output_w == mjpeg->coded_w &&
613 mjpeg->output_h == mjpeg->coded_h)
615 for(i = 0; i < compressor->coded_field_h; i++)
617 int input_row = get_input_row(mjpeg, compressor, i);
618 compressor->rows[0][i] = mjpeg->y_argument +
619 mjpeg->coded_w * input_row;
620 if(i < compressor->coded_field_h / 2)
622 compressor->rows[1][i] = mjpeg->u_argument +
623 (mjpeg->coded_w / 2) * input_row;
624 compressor->rows[2][i] = mjpeg->v_argument +
625 (mjpeg->coded_w / 2) * input_row;
631 for(i = 0; i < compressor->coded_field_h; i++)
633 int input_row = get_input_row(mjpeg, compressor, i);
634 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
635 if(i < compressor->coded_field_h / 2)
637 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
638 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
647 static void delete_rows(mjpeg_compressor *compressor)
649 if(compressor->rows[0])
651 delete [] compressor->rows[0];
652 delete [] compressor->rows[1];
653 delete [] compressor->rows[2];
657 /* replacement routine to suppress decompress warnings */
658 static void mjpeg_emit_message(j_common_ptr cinfo, int msg_level)
660 struct jpeg_error_mgr * err = cinfo->err;
663 if(err->trace_level >= 3)
664 (*err->output_message) (cinfo);
666 if (err->trace_level >= msg_level)
667 (*err->output_message) (cinfo);
671 static void new_jpeg_objects(mjpeg_compressor *engine)
673 engine->jpeg_decompress.err = jpeg_std_error(&(engine->jpeg_error.pub));
674 engine->jpeg_error.pub.error_exit = mjpeg_error_exit;
675 engine->jpeg_error.pub.emit_message = mjpeg_emit_message;
676 /* Ideally the error handler would be set here but it must be called in a thread */
677 jpeg_create_decompress(&(engine->jpeg_decompress));
678 engine->jpeg_decompress.raw_data_out = TRUE;
679 #if JPEG_LIB_VERSION >= 70
680 engine->jpeg_decompress.do_fancy_upsampling = FALSE;
682 engine->jpeg_decompress.dct_method = JDCT_IFAST;
685 static void delete_jpeg_objects(mjpeg_compressor *engine)
687 jpeg_destroy_decompress(&(engine->jpeg_decompress));
692 static void unlock_compress_loop(mjpeg_compressor *engine)
694 pthread_mutex_unlock(&(engine->input_lock));
697 static void lock_compress_loop(mjpeg_compressor *engine)
699 pthread_mutex_lock(&(engine->output_lock));
702 // Make temp rows for compressor
703 static void get_mcu_rows(mjpeg_t *mjpeg,
704 mjpeg_compressor *engine,
708 for(i = 0; i < 3; i++)
710 for(j = 0; j < 16; j++)
712 if(i > 0 && j >= 8 && mjpeg->jpeg_color_model == BC_YUV420P) break;
714 scanline = start_row;
715 if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) scanline /= 2;
717 if(scanline >= engine->coded_field_h) scanline = engine->coded_field_h - 1;
718 engine->mcu_rows[i][j] = engine->rows[i][scanline];
724 static void decompress_field(mjpeg_compressor *engine)
726 mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
727 long buffer_offset = engine->instance * mjpeg->input_field2;
728 unsigned char *buffer = mjpeg->input_data + buffer_offset;
731 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
732 if(engine->instance == 0 && mjpeg->fields > 1)
733 buffer_size = mjpeg->input_field2 - buffer_offset;
735 buffer_size = mjpeg->input_size - buffer_offset;
739 if(setjmp(engine->jpeg_error.setjmp_buffer))
741 /* If we get here, the JPEG code has signaled an error. */
742 printf("decompress_field %d\n", __LINE__);
743 delete_jpeg_objects(engine);
744 printf("decompress_field %d\n", __LINE__);
745 new_jpeg_objects(engine);
746 printf("decompress_field %d\n", __LINE__);
748 printf("decompress_field %d\n", __LINE__);
752 //printf("decompress_field 2\n");
753 jpeg_buffer_src(&engine->jpeg_decompress,
756 jpeg_read_header(&engine->jpeg_decompress, TRUE);
758 if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
759 engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
760 engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
761 engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
762 jpeg_load_dht( &engine->jpeg_decompress,
764 engine->jpeg_decompress.ac_huff_tbl_ptrs,
765 engine->jpeg_decompress.dc_huff_tbl_ptrs );
766 // Reset by jpeg_read_header
767 engine->jpeg_decompress.raw_data_out = TRUE;
768 #if JPEG_LIB_VERSION >= 70
769 engine->jpeg_decompress.do_fancy_upsampling = FALSE;
771 jpeg_start_decompress(&engine->jpeg_decompress);
773 // Generate colormodel from jpeg sampling
774 if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
775 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
776 mjpeg->jpeg_color_model = BC_YUV420P;
778 if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
779 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
780 mjpeg->jpeg_color_model = BC_YUV422P;
782 mjpeg->jpeg_color_model = BC_YUV444P;
784 if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
785 mjpeg->greyscale = 1;
787 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
788 // Must be here because the color model isn't known until now
789 pthread_mutex_lock(&(mjpeg->decompress_init));
790 allocate_temps(mjpeg);
791 pthread_mutex_unlock(&(mjpeg->decompress_init));
792 get_rows(mjpeg, engine);
794 //printf("decompress_field 30\n");
796 while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
798 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
799 jpeg_read_raw_data(&engine->jpeg_decompress,
801 engine->coded_field_h);
803 jpeg_finish_decompress(&engine->jpeg_decompress);
805 //printf("decompress_field 40\n");
811 void mjpeg_decompress_loop(mjpeg_compressor *engine)
815 pthread_mutex_lock(&engine->input_lock);
818 decompress_field(engine);
820 pthread_mutex_unlock(&(engine->output_lock));
825 static void compress_field(mjpeg_compressor *engine)
827 mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
829 //printf("compress_field 1\n");
830 get_rows(mjpeg, engine);
831 reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
832 jpeg_buffer_dest(&engine->jpeg_compress, engine);
835 engine->jpeg_compress.raw_data_in = TRUE;
836 #if JPEG_LIB_VERSION >= 70
837 engine->jpeg_compress.do_fancy_downsampling = FALSE;
839 jpeg_start_compress(&engine->jpeg_compress, TRUE);
841 while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
843 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
845 jpeg_write_raw_data(&engine->jpeg_compress,
847 engine->coded_field_h);
849 jpeg_finish_compress(&engine->jpeg_compress);
850 //printf("compress_field 2\n");
854 void mjpeg_compress_loop(mjpeg_compressor *engine)
858 pthread_mutex_lock(&engine->input_lock);
861 compress_field(engine);
863 pthread_mutex_unlock(&engine->output_lock);
867 static void delete_temps(mjpeg_t *mjpeg)
871 delete [] mjpeg->temp_data;
872 delete [] mjpeg->temp_rows[0];
873 delete [] mjpeg->temp_rows[1];
874 delete [] mjpeg->temp_rows[2];
875 mjpeg->temp_data = 0;
879 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
881 mjpeg_compressor *result = new mjpeg_compressor();
882 memset(result, 0, sizeof(mjpeg_compressor));
884 pthread_mutexattr_t mutex_attr;
886 result->mjpeg = mjpeg;
887 result->instance = instance;
888 new_jpeg_objects(result);
889 result->field_h = mjpeg->output_h / mjpeg->fields;
890 result->coded_field_h = (result->field_h % 16) ?
891 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
893 result->mcu_rows[0] = new unsigned char *[16];
894 result->mcu_rows[1] = new unsigned char *[16];
895 result->mcu_rows[2] = new unsigned char *[16];
897 pthread_mutexattr_init(&mutex_attr);
898 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
899 pthread_mutex_init(&(result->input_lock), &mutex_attr);
900 pthread_mutex_lock(&(result->input_lock));
901 pthread_mutex_init(&(result->output_lock), &mutex_attr);
902 pthread_mutex_lock(&(result->output_lock));
904 pthread_attr_init(&attr);
905 pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_decompress_loop, result);
910 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
913 pthread_mutex_unlock(&(engine->input_lock));
914 pthread_join(engine->tid, 0);
915 pthread_mutex_destroy(&(engine->input_lock));
916 pthread_mutex_destroy(&(engine->output_lock));
917 jpeg_destroy_decompress(&(engine->jpeg_decompress));
919 delete [] engine->mcu_rows[0];
920 delete [] engine->mcu_rows[1];
921 delete [] engine->mcu_rows[2];
925 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
928 pthread_mutexattr_t mutex_attr;
929 mjpeg_compressor *result = new mjpeg_compressor();
930 memset(result, 0, sizeof(mjpeg_compressor));
932 result->field_h = mjpeg->output_h / mjpeg->fields;
933 result->coded_field_h = (result->field_h % 16) ?
934 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
935 result->mjpeg = mjpeg;
936 result->instance = instance;
937 result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
938 jpeg_create_compress(&(result->jpeg_compress));
939 result->jpeg_compress.image_width = mjpeg->output_w;
940 result->jpeg_compress.image_height = result->field_h;
941 result->jpeg_compress.input_components = 3;
942 result->jpeg_compress.in_color_space = JCS_RGB;
943 jpeg_set_defaults(&(result->jpeg_compress));
944 result->jpeg_compress.input_components = 3;
945 result->jpeg_compress.in_color_space = JCS_RGB;
946 jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
949 result->jpeg_compress.dct_method = JDCT_FLOAT;
951 result->jpeg_compress.dct_method = JDCT_IFAST;
952 // result->jpeg_compress.dct_method = JDCT_ISLOW;
955 switch(mjpeg->fields)
958 mjpeg->jpeg_color_model = BC_YUV420P;
959 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
960 result->jpeg_compress.comp_info[0].v_samp_factor = 2;
961 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
962 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
963 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
964 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
967 mjpeg->jpeg_color_model = BC_YUV422P;
968 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
969 result->jpeg_compress.comp_info[0].v_samp_factor = 1;
970 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
971 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
972 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
973 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
976 allocate_temps(mjpeg);
978 result->mcu_rows[0] = new unsigned char *[16];
979 result->mcu_rows[1] = new unsigned char *[16];
980 result->mcu_rows[2] = new unsigned char *[16];
982 pthread_mutexattr_init(&mutex_attr);
983 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
984 pthread_mutex_init(&(result->input_lock), &mutex_attr);
985 pthread_mutex_lock(&(result->input_lock));
986 pthread_mutex_init(&(result->output_lock), &mutex_attr);
987 pthread_mutex_lock(&(result->output_lock));
989 pthread_attr_init(&attr);
990 pthread_create(&(result->tid), &attr, (void*(*)(void*))mjpeg_compress_loop, result);
995 void mjpeg_delete_compressor(mjpeg_compressor *engine)
998 pthread_mutex_unlock(&(engine->input_lock));
999 pthread_join(engine->tid, 0);
1000 pthread_mutex_destroy(&(engine->input_lock));
1001 pthread_mutex_destroy(&(engine->output_lock));
1002 jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
1003 if(engine->output_buffer) delete [] engine->output_buffer;
1004 delete_rows(engine);
1005 delete [] engine->mcu_rows[0];
1006 delete [] engine->mcu_rows[1];
1007 delete [] engine->mcu_rows[2];
1011 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
1013 return mjpeg->output_data;
1016 long mjpeg_output_field2(mjpeg_t *mjpeg)
1018 return mjpeg->output_field2;
1021 long mjpeg_output_size(mjpeg_t *mjpeg)
1023 return mjpeg->output_size;
1026 long mjpeg_output_allocated(mjpeg_t *mjpeg)
1028 return mjpeg->output_allocated;
1031 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
1033 mjpeg->output_size = output_size;
1037 int mjpeg_compress(mjpeg_t *mjpeg,
1038 unsigned char **row_pointers,
1039 unsigned char *y_plane,
1040 unsigned char *u_plane,
1041 unsigned char *v_plane,
1046 int corrected_fields = mjpeg->fields;
1047 mjpeg->color_model = color_model;
1050 //printf("mjpeg_compress 1 %d\n", color_model);
1051 /* Reset output buffer */
1052 reset_buffer(&mjpeg->output_data,
1053 &mjpeg->output_size,
1054 &mjpeg->output_allocated);
1056 /* Create compression engines as needed */
1057 for(i = 0; i < mjpeg->fields; i++)
1059 if(!mjpeg->compressors[i])
1061 mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
1065 /* Arm YUV buffers */
1066 mjpeg->row_argument = row_pointers;
1067 mjpeg->y_argument = y_plane;
1068 mjpeg->u_argument = u_plane;
1069 mjpeg->v_argument = v_plane;
1070 // User colormodel doesn't match encoder colormodel
1071 // Copy to interlacing buffer first
1072 if(mjpeg->color_model != mjpeg->jpeg_color_model ||
1073 mjpeg->output_w != mjpeg->coded_w ||
1074 mjpeg->output_h != mjpeg->coded_h)
1077 * printf("mjpeg_compress %d %d %d %d\n",
1078 * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
1080 BC_CModels::transfer(0,
1082 mjpeg->temp_rows[0][0],
1083 mjpeg->temp_rows[1][0],
1084 mjpeg->temp_rows[2][0],
1097 mjpeg->jpeg_color_model,
1103 /* Start the compressors on the image fields */
1104 if(mjpeg->deinterlace) corrected_fields = 1;
1105 for(i = 0; i < corrected_fields && !result; i++)
1107 unlock_compress_loop(mjpeg->compressors[i]);
1109 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
1111 lock_compress_loop(mjpeg->compressors[i]);
1115 /* Wait for the compressors and store in master output */
1116 for(i = 0; i < corrected_fields && !result; i++)
1118 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
1120 lock_compress_loop(mjpeg->compressors[i]);
1123 append_buffer(&mjpeg->output_data,
1124 &mjpeg->output_size,
1125 &mjpeg->output_allocated,
1126 mjpeg->compressors[i]->output_buffer,
1127 mjpeg->compressors[i]->output_size);
1128 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
1131 if(corrected_fields < mjpeg->fields)
1133 append_buffer(&mjpeg->output_data,
1134 &mjpeg->output_size,
1135 &mjpeg->output_allocated,
1136 mjpeg->compressors[0]->output_buffer,
1137 mjpeg->compressors[0]->output_size);
1139 //printf("mjpeg_compress 2\n");
1145 int mjpeg_decompress(mjpeg_t *mjpeg,
1146 unsigned char *buffer,
1149 unsigned char **row_pointers,
1150 unsigned char *y_plane,
1151 unsigned char *u_plane,
1152 unsigned char *v_plane,
1157 int got_first_thread = 0;
1159 //printf("mjpeg_decompress 1 %d\n", color_model);
1160 if(buffer_len == 0) return 1;
1161 if(input_field2 == 0 && mjpeg->fields > 1) return 1;
1163 //printf("mjpeg_decompress 2\n");
1164 /* Create decompression engines as needed */
1165 for(i = 0; i < mjpeg->fields; i++)
1167 if(!mjpeg->decompressors[i])
1169 mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
1173 //printf("mjpeg_decompress 3\n");
1174 /* Arm YUV buffers */
1175 mjpeg->row_argument = row_pointers;
1176 mjpeg->y_argument = y_plane;
1177 mjpeg->u_argument = u_plane;
1178 mjpeg->v_argument = v_plane;
1179 mjpeg->input_data = buffer;
1180 mjpeg->input_size = buffer_len;
1181 mjpeg->input_field2 = input_field2;
1182 mjpeg->color_model = color_model;
1185 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1186 /* Start decompressors */
1187 for(i = 0; i < mjpeg->fields && !result; i++)
1189 //printf("mjpeg_decompress 5\n");
1190 unlock_compress_loop(mjpeg->decompressors[i]);
1191 //printf("mjpeg_decompress 6\n");
1193 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1194 // For single CPUs, don't want two threads running simultaneously
1195 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
1197 //printf("mjpeg_decompress 7\n");
1198 lock_compress_loop(mjpeg->decompressors[i]);
1199 //printf("mjpeg_decompress 8\n");
1200 if(i == 0) got_first_thread = 1;
1204 //printf("mjpeg_decompress 10\n");
1205 /* Wait for decompressors */
1206 for(i = 0; i < mjpeg->fields && !result; i++)
1210 if(i > 0 || !got_first_thread)
1211 lock_compress_loop(mjpeg->decompressors[i]);
1215 /* Convert colormodel */
1216 // User colormodel didn't match decompressor
1218 * if(!mjpeg->error &&
1219 * (mjpeg->jpeg_color_model != mjpeg->color_model ||
1220 * mjpeg->coded_w != mjpeg->output_w ||
1221 * mjpeg->coded_h != mjpeg->output_h))
1224 //printf("mjpeg_decompress 6 %d %d %d %d\n", mjpeg->coded_w, mjpeg->coded_h, mjpeg->output_w, mjpeg->output_h);
1225 if((mjpeg->jpeg_color_model != mjpeg->color_model ||
1226 mjpeg->coded_w != mjpeg->output_w ||
1227 mjpeg->coded_h != mjpeg->output_h)
1229 (mjpeg->temp_data ||
1232 unsigned char *y_in = mjpeg->temp_rows[0][0];
1233 unsigned char *u_in = mjpeg->temp_rows[1][0];
1234 unsigned char *v_in = mjpeg->temp_rows[2][0];
1238 * printf("mjpeg_decompress 7 coded_w=%d coded_h=%d output_w=%d output_h=%d out_rowspan=%d in_colormodel=%d out_colormodel=%d\n",
1243 * mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w,
1244 * mjpeg->jpeg_color_model,
1245 * mjpeg->color_model);
1248 BC_CModels::transfer(row_pointers,
1264 mjpeg->jpeg_color_model,
1268 mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1269 //printf("mjpeg_decompress 8\n");
1275 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
1277 mjpeg->deinterlace = value;
1280 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
1282 mjpeg->quality = quality;
1285 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
1287 mjpeg->use_float = use_float;
1290 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
1295 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
1297 mjpeg->rowspan = rowspan;
1300 int mjpeg_get_fields(mjpeg_t *mjpeg)
1302 return mjpeg->fields;
1306 mjpeg_t* mjpeg_new(int w,
1310 mjpeg_t *result = new mjpeg_t();
1311 memset(result, 0, sizeof(*result));
1312 pthread_mutexattr_t mutex_attr;
1314 result->output_w = w;
1315 result->output_h = h;
1316 result->fields = fields;
1317 result->color_model = BC_RGB888;
1319 result->quality = 80;
1320 result->use_float = 0;
1322 pthread_mutexattr_init(&mutex_attr);
1323 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1324 pthread_mutex_init(&(result->decompress_init), &mutex_attr);
1327 // Calculate coded dimensions
1328 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1330 result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
1333 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
1335 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
1339 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1346 void mjpeg_delete(mjpeg_t *mjpeg)
1349 //printf("mjpeg_delete 1\n");
1350 for(i = 0; i < mjpeg->fields; i++)
1352 //printf("mjpeg_delete 2\n");
1353 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
1354 //printf("mjpeg_delete 3\n");
1355 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
1356 //printf("mjpeg_delete 4\n");
1358 //printf("mjpeg_delete 5\n");
1359 delete_temps(mjpeg);
1360 //printf("mjpeg_delete 6\n");
1361 delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
1362 //printf("mjpeg_delete 7\n");
1364 //printf("mjpeg_delete 2\n");
1368 /* Open up a space to insert a marker */
1369 static void insert_space(unsigned char **buffer,
1371 long *buffer_allocated,
1376 // Make sure enough space is available
1377 if(*buffer_allocated - *buffer_size < space_len)
1379 *buffer_allocated += space_len;
1380 unsigned char *new_buffer = new unsigned char[*buffer_allocated];
1381 memcpy(new_buffer, *buffer, *buffer_size);
1383 *buffer = new_buffer;
1387 for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
1391 (*buffer)[out] = (*buffer)[in];
1393 *buffer_size += space_len;
1397 static inline int nextbyte(unsigned char *data, long *offset, long length)
1399 if(length - *offset < 1) return 0;
1401 return (unsigned char)data[*offset - 1];
1404 static inline int read_int32(unsigned char *data, long *offset, long length)
1406 if(length - *offset < 4)
1412 return ((((unsigned int)data[*offset - 4]) << 24) |
1413 (((unsigned int)data[*offset - 3]) << 16) |
1414 (((unsigned int)data[*offset - 2]) << 8) |
1415 (((unsigned int)data[*offset - 1])));
1418 static inline int read_int16(unsigned char *data, long *offset, long length)
1420 if(length - *offset < 2)
1427 return ((((unsigned int)data[*offset - 2]) << 8) |
1428 (((unsigned int)data[*offset - 1])));
1431 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
1433 if(length - *offset < 1)
1440 return (unsigned char)data[*offset - 1];
1443 static inline int next_int16(unsigned char *data, long *offset, long length)
1445 if(length - *offset < 2)
1450 return ((((unsigned int)data[*offset]) << 8) |
1451 (((unsigned int)data[*offset + 1])));
1454 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
1456 if(length - *offset < 4)
1463 data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
1464 data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
1465 data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
1466 data[(*offset)++] = (unsigned char)(value & 0xff);
1470 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
1472 if(length - *offset < 1)
1478 data[(*offset)++] = value;
1482 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
1484 while(*offset < buffer_size - 1) {
1485 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff) {
1487 return buffer[*offset - 1];
1494 /* Find the next marker after offset and return 0 on success */
1495 static int find_marker(unsigned char *buffer,
1498 unsigned long marker_type)
1502 while(!result && *offset < buffer_size - 1)
1504 unsigned int marker = next_marker(buffer, offset, buffer_size);
1505 if(marker == (marker_type & 0xff)) result = 1;
1515 int padded_field_size;
1528 int unpadded_field_size;
1531 #define LML_MARKER_SIZE 0x2c
1532 #define LML_MARKER_TAG 0xffe3
1533 void insert_lml33_markers(unsigned char **buffer,
1534 long *field2_offset,
1536 long *buffer_allocated)
1538 long marker_offset = -1;
1540 /* Search for existing marker to replace */
1541 // marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
1543 /* Insert new marker */
1544 if(marker_offset < 0)
1547 insert_space(buffer,
1555 static int qt_table_offsets(unsigned char *buffer,
1566 bzero(header, sizeof(qt_hdr_t) * 2);
1568 // Read every marker to get the offsets for the headers
1569 for(field = 0; field < 2; field++)
1575 marker = next_marker(buffer,
1584 // The first field may be padded
1587 header[0].next_offset =
1588 header[0].padded_field_size =
1595 // Quicktime marker already exists. Abort.
1596 if(buffer[offset + 6] == 'm' &&
1597 buffer[offset + 7] == 'j' &&
1598 buffer[offset + 8] == 'p' &&
1599 buffer[offset + 9] == 'a')
1607 if(!header[field].quant_offset)
1609 header[field].quant_offset = offset - 2;
1611 header[field].quant_offset -= header[0].next_offset;
1613 len = read_int16(buffer, &offset, buffer_size);
1618 if(!header[field].huffman_offset)
1620 header[field].huffman_offset = offset - 2;
1622 header[field].huffman_offset -= header[0].next_offset;
1624 len = read_int16(buffer, &offset, buffer_size);
1629 if(!header[field].image_offset)
1631 header[field].image_offset = offset - 2;
1633 header[field].image_offset -= header[0].next_offset;
1635 len = read_int16(buffer, &offset, buffer_size);
1640 header[field].scan_offset = offset - 2;
1642 header[field].scan_offset -= header[0].next_offset;
1643 len = read_int16(buffer, &offset, buffer_size);
1645 header[field].data_offset = offset + len;
1647 header[field].data_offset -= header[0].next_offset;
1654 header[field].field_size =
1655 header[field].padded_field_size =
1656 offset - header[0].next_offset;
1657 header[field].next_offset = 0;
1661 // Often misses second SOI but gets first EOI
1662 // header[0].next_offset =
1663 // header[0].padded_field_size =
1666 //printf("table_offsets M_EOI %d %x\n", field, offset);
1672 // Junk appears between fields
1674 // len = read_int16(buffer, &offset, buffer_size);
1679 if(!done) offset += len;
1680 if(offset >= buffer_size) done = 1;
1682 //printf("qt_table_offsets 10 %d\n", field);
1688 static void insert_quicktime_marker(unsigned char *buffer,
1693 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1694 ((unsigned long)M_APP1 << 16) |
1695 (QUICKTIME_MARKER_SIZE - 2));
1696 write_int32(buffer, &offset, buffer_size, 0);
1697 write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1698 write_int32(buffer, &offset, buffer_size, header->field_size);
1699 write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1700 write_int32(buffer, &offset, buffer_size, header->next_offset);
1701 write_int32(buffer, &offset, buffer_size, header->quant_offset);
1702 write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1703 write_int32(buffer, &offset, buffer_size, header->image_offset);
1704 write_int32(buffer, &offset, buffer_size, header->scan_offset);
1705 write_int32(buffer, &offset, buffer_size, header->data_offset);
1709 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1711 long *buffer_allocated,
1713 long *field2_offset)
1717 *field2_offset = -1;
1719 if(fields < 2) return;
1722 // Get offsets for tables in both fields
1723 exists = qt_table_offsets(*buffer, *buffer_size, header);
1725 // APP1 for quicktime already exists
1728 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1729 // header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1730 //if(*field2_offset == 0)
1731 // fwrite(*buffer, *buffer_size, 1, stdout);
1735 header[0].field_size += QUICKTIME_MARKER_SIZE;
1736 header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1737 header[0].next_offset += QUICKTIME_MARKER_SIZE;
1738 header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1739 header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1740 header[0].image_offset += QUICKTIME_MARKER_SIZE;
1741 header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1742 header[0].data_offset += QUICKTIME_MARKER_SIZE;
1743 header[1].field_size += QUICKTIME_MARKER_SIZE;
1744 header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1745 header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1746 header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1747 header[1].image_offset += QUICKTIME_MARKER_SIZE;
1748 header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1749 header[1].data_offset += QUICKTIME_MARKER_SIZE;
1750 *field2_offset = header[0].next_offset;
1754 // Insert APP1 marker
1755 insert_space(buffer,
1759 QUICKTIME_MARKER_SIZE);
1761 insert_quicktime_marker(*buffer,
1766 insert_space(buffer,
1769 header[0].next_offset + 2,
1770 QUICKTIME_MARKER_SIZE);
1772 header[1].next_offset = 0;
1773 insert_quicktime_marker(*buffer,
1775 header[0].next_offset + 2,
1780 static int avi_table_offsets(unsigned char *buffer,
1784 int field2 = mjpeg_get_field2(buffer, buffer_size);
1786 header[0].field_number = 1;
1787 header[0].field_size = field2;
1788 header[0].unpadded_field_size = field2;
1790 header[1].field_number = 2;
1791 header[1].field_size = buffer_size - field2;
1792 header[1].unpadded_field_size = buffer_size - field2;
1796 static void insert_avi_marker(unsigned char *buffer,
1801 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1802 ((unsigned long)M_APP0 << 16) |
1803 (AVI_MARKER_SIZE - 2));
1804 write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1806 // One version of McRoweSoft only allows field polarity while
1807 // another version allows field size.
1808 write_char(buffer, &offset, buffer_size, header->field_number);
1809 write_char(buffer, &offset, buffer_size, 0);
1810 write_int32(buffer, &offset, buffer_size, header->field_size);
1811 write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1814 void mjpeg_insert_avi_markers(unsigned char **buffer,
1816 long *buffer_allocated,
1818 long *field2_offset)
1820 avi_hdr_t header[2];
1822 *field2_offset = -1;
1825 // Test for existing marker
1826 if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1828 if((*buffer)[offset + 2] == 'A' &&
1829 (*buffer)[offset + 3] == 'V' &&
1830 (*buffer)[offset + 4] == 'I' &&
1831 (*buffer)[offset + 5] == '1')
1836 avi_table_offsets(*buffer, *buffer_size, header);
1838 header[0].field_size += AVI_MARKER_SIZE;
1839 header[0].unpadded_field_size += AVI_MARKER_SIZE;
1840 header[1].field_size += AVI_MARKER_SIZE;
1841 header[1].unpadded_field_size += AVI_MARKER_SIZE;
1842 *field2_offset = header[0].field_size;
1844 // Insert APP0 marker into field 1
1845 insert_space(buffer,
1850 insert_avi_marker(*buffer,
1855 insert_space(buffer,
1860 insert_avi_marker(*buffer,
1870 static void read_avi_markers(unsigned char *buffer,
1875 int marker_count = 0;
1877 int marker_size = 0;
1878 while(marker_count < 2 && offset < buffer_size && !result)
1880 result = find_marker(buffer,
1884 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1887 if(!result && marker_size >= 16)
1889 // Marker size, AVI1
1892 header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1893 read_char(buffer, &offset, buffer_size);
1894 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1895 header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1902 static void read_quicktime_markers(unsigned char *buffer,
1907 int marker_count = 0;
1910 while(marker_count < 2 && offset < buffer_size && !result)
1912 result = find_marker(buffer,
1920 read_int16(buffer, &offset, buffer_size);
1922 read_int32(buffer, &offset, buffer_size);
1924 read_int32(buffer, &offset, buffer_size);
1926 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1927 header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1928 header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1929 header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1930 header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1931 header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1932 header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1933 header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1937 //printf("read_quicktime_markers 1 %d\n", marker_count);
1940 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1943 bzero(&header, sizeof(qt_hdr_t) * 2);
1945 read_quicktime_markers(buffer, buffer_size, header);
1946 return header[0].next_offset;
1949 long mjpeg_get_avi_field2(unsigned char *buffer,
1951 int *field_dominance)
1953 avi_hdr_t header[2];
1954 bzero(&header, sizeof(avi_hdr_t) * 2);
1955 read_avi_markers(buffer, buffer_size, header);
1957 *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1959 // One version of McRoweSoft only allows field polarity while
1960 // another version allows field size.
1961 if(header[0].field_size)
1963 return header[0].field_size;
1967 return mjpeg_get_field2(buffer, buffer_size);
1972 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1974 int total_fields = 0;
1975 long field2_offset = 0;
1978 for(i = 0; i < buffer_size; i++)
1980 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1984 if(total_fields == 2) break;
1987 return field2_offset;
1990 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1997 *h = (data[offset + 3] << 8) | (data[offset + 4]);
1998 *w = (data[offset + 5] << 8) | (data[offset + 6]);