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,
707 int i, j, scanline, lastline;
708 for(i = 0; i < 3; i++)
710 for(j = 0; j < 16; j++)
712 scanline = start_row;
713 lastline = engine->coded_field_h;
714 if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) {
715 lastline /= 2; scanline /= 2;
718 if(scanline >= lastline) scanline = lastline - 1;
719 engine->mcu_rows[i][j] = engine->rows[i][scanline];
725 static void decompress_field(mjpeg_compressor *engine)
727 mjpeg_t *mjpeg = (mjpeg_t *)engine->mjpeg;
728 long buffer_offset = engine->instance * mjpeg->input_field2;
729 unsigned char *buffer = mjpeg->input_data + buffer_offset;
732 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
733 if(engine->instance == 0 && mjpeg->fields > 1)
734 buffer_size = mjpeg->input_field2 - buffer_offset;
736 buffer_size = mjpeg->input_size - buffer_offset;
740 if(setjmp(engine->jpeg_error.setjmp_buffer))
742 /* If we get here, the JPEG code has signaled an error. */
743 printf("decompress_field %d\n", __LINE__);
744 delete_jpeg_objects(engine);
745 printf("decompress_field %d\n", __LINE__);
746 new_jpeg_objects(engine);
747 printf("decompress_field %d\n", __LINE__);
749 printf("decompress_field %d\n", __LINE__);
753 //printf("decompress_field 2\n");
754 jpeg_buffer_src(&engine->jpeg_decompress,
757 jpeg_read_header(&engine->jpeg_decompress, TRUE);
759 if ( engine->jpeg_decompress.ac_huff_tbl_ptrs[0] == NULL &&
760 engine->jpeg_decompress.ac_huff_tbl_ptrs[1] == NULL &&
761 engine->jpeg_decompress.dc_huff_tbl_ptrs[0] == NULL &&
762 engine->jpeg_decompress.dc_huff_tbl_ptrs[1] == NULL )
763 jpeg_load_dht( &engine->jpeg_decompress,
765 engine->jpeg_decompress.ac_huff_tbl_ptrs,
766 engine->jpeg_decompress.dc_huff_tbl_ptrs );
767 // Reset by jpeg_read_header
768 engine->jpeg_decompress.raw_data_out = TRUE;
769 #if JPEG_LIB_VERSION >= 70
770 engine->jpeg_decompress.do_fancy_upsampling = FALSE;
772 jpeg_start_decompress(&engine->jpeg_decompress);
774 // Generate colormodel from jpeg sampling
775 if( engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
776 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
777 mjpeg->jpeg_color_model = BC_YUV420P;
778 else 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;
1532 static int qt_table_offsets(unsigned char *buffer,
1543 bzero(header, sizeof(qt_hdr_t) * 2);
1545 // Read every marker to get the offsets for the headers
1546 for(field = 0; field < 2; field++)
1552 marker = next_marker(buffer,
1561 // The first field may be padded
1564 header[0].next_offset =
1565 header[0].padded_field_size =
1572 // Quicktime marker already exists. Abort.
1573 if(buffer[offset + 6] == 'm' &&
1574 buffer[offset + 7] == 'j' &&
1575 buffer[offset + 8] == 'p' &&
1576 buffer[offset + 9] == 'a')
1584 if(!header[field].quant_offset)
1586 header[field].quant_offset = offset - 2;
1588 header[field].quant_offset -= header[0].next_offset;
1590 len = read_int16(buffer, &offset, buffer_size);
1595 if(!header[field].huffman_offset)
1597 header[field].huffman_offset = offset - 2;
1599 header[field].huffman_offset -= header[0].next_offset;
1601 len = read_int16(buffer, &offset, buffer_size);
1606 if(!header[field].image_offset)
1608 header[field].image_offset = offset - 2;
1610 header[field].image_offset -= header[0].next_offset;
1612 len = read_int16(buffer, &offset, buffer_size);
1617 header[field].scan_offset = offset - 2;
1619 header[field].scan_offset -= header[0].next_offset;
1620 len = read_int16(buffer, &offset, buffer_size);
1622 header[field].data_offset = offset + len;
1624 header[field].data_offset -= header[0].next_offset;
1631 header[field].field_size =
1632 header[field].padded_field_size =
1633 offset - header[0].next_offset;
1634 header[field].next_offset = 0;
1638 // Often misses second SOI but gets first EOI
1639 // header[0].next_offset =
1640 // header[0].padded_field_size =
1643 //printf("table_offsets M_EOI %d %x\n", field, offset);
1649 // Junk appears between fields
1651 // len = read_int16(buffer, &offset, buffer_size);
1656 if(!done) offset += len;
1657 if(offset >= buffer_size) done = 1;
1659 //printf("qt_table_offsets 10 %d\n", field);
1665 static void insert_quicktime_marker(unsigned char *buffer,
1670 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1671 ((unsigned long)M_APP1 << 16) |
1672 (QUICKTIME_MARKER_SIZE - 2));
1673 write_int32(buffer, &offset, buffer_size, 0);
1674 write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1675 write_int32(buffer, &offset, buffer_size, header->field_size);
1676 write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1677 write_int32(buffer, &offset, buffer_size, header->next_offset);
1678 write_int32(buffer, &offset, buffer_size, header->quant_offset);
1679 write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1680 write_int32(buffer, &offset, buffer_size, header->image_offset);
1681 write_int32(buffer, &offset, buffer_size, header->scan_offset);
1682 write_int32(buffer, &offset, buffer_size, header->data_offset);
1686 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1688 long *buffer_allocated,
1690 long *field2_offset)
1694 *field2_offset = -1;
1696 if(fields < 2) return;
1699 // Get offsets for tables in both fields
1700 exists = qt_table_offsets(*buffer, *buffer_size, header);
1702 // APP1 for quicktime already exists
1705 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1706 // header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1707 //if(*field2_offset == 0)
1708 // fwrite(*buffer, *buffer_size, 1, stdout);
1712 header[0].field_size += QUICKTIME_MARKER_SIZE;
1713 header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1714 header[0].next_offset += QUICKTIME_MARKER_SIZE;
1715 header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1716 header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1717 header[0].image_offset += QUICKTIME_MARKER_SIZE;
1718 header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1719 header[0].data_offset += QUICKTIME_MARKER_SIZE;
1720 header[1].field_size += QUICKTIME_MARKER_SIZE;
1721 header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1722 header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1723 header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1724 header[1].image_offset += QUICKTIME_MARKER_SIZE;
1725 header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1726 header[1].data_offset += QUICKTIME_MARKER_SIZE;
1727 *field2_offset = header[0].next_offset;
1731 // Insert APP1 marker
1732 insert_space(buffer,
1736 QUICKTIME_MARKER_SIZE);
1738 insert_quicktime_marker(*buffer,
1743 insert_space(buffer,
1746 header[0].next_offset + 2,
1747 QUICKTIME_MARKER_SIZE);
1749 header[1].next_offset = 0;
1750 insert_quicktime_marker(*buffer,
1752 header[0].next_offset + 2,
1757 static int avi_table_offsets(unsigned char *buffer,
1761 int field2 = mjpeg_get_field2(buffer, buffer_size);
1763 header[0].field_number = 1;
1764 header[0].field_size = field2;
1765 header[0].unpadded_field_size = field2;
1767 header[1].field_number = 2;
1768 header[1].field_size = buffer_size - field2;
1769 header[1].unpadded_field_size = buffer_size - field2;
1773 static void insert_avi_marker(unsigned char *buffer,
1778 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1779 ((unsigned long)M_APP0 << 16) |
1780 (AVI_MARKER_SIZE - 2));
1781 write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1783 // One version of McRoweSoft only allows field polarity while
1784 // another version allows field size.
1785 write_char(buffer, &offset, buffer_size, header->field_number);
1786 write_char(buffer, &offset, buffer_size, 0);
1787 write_int32(buffer, &offset, buffer_size, header->field_size);
1788 write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1791 void mjpeg_insert_avi_markers(unsigned char **buffer,
1793 long *buffer_allocated,
1795 long *field2_offset)
1797 avi_hdr_t header[2];
1799 *field2_offset = -1;
1802 // Test for existing marker
1803 if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1805 if((*buffer)[offset + 2] == 'A' &&
1806 (*buffer)[offset + 3] == 'V' &&
1807 (*buffer)[offset + 4] == 'I' &&
1808 (*buffer)[offset + 5] == '1')
1813 avi_table_offsets(*buffer, *buffer_size, header);
1815 header[0].field_size += AVI_MARKER_SIZE;
1816 header[0].unpadded_field_size += AVI_MARKER_SIZE;
1817 header[1].field_size += AVI_MARKER_SIZE;
1818 header[1].unpadded_field_size += AVI_MARKER_SIZE;
1819 *field2_offset = header[0].field_size;
1821 // Insert APP0 marker into field 1
1822 insert_space(buffer,
1827 insert_avi_marker(*buffer,
1832 insert_space(buffer,
1837 insert_avi_marker(*buffer,
1847 static void read_avi_markers(unsigned char *buffer,
1852 int marker_count = 0;
1854 int marker_size = 0;
1855 while(marker_count < 2 && offset < buffer_size && !result)
1857 result = find_marker(buffer,
1861 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1864 if(!result && marker_size >= 16)
1866 // Marker size, AVI1
1869 header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1870 read_char(buffer, &offset, buffer_size);
1871 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1872 header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1879 static void read_quicktime_markers(unsigned char *buffer,
1884 int marker_count = 0;
1887 while(marker_count < 2 && offset < buffer_size && !result)
1889 result = find_marker(buffer,
1897 read_int16(buffer, &offset, buffer_size);
1899 read_int32(buffer, &offset, buffer_size);
1901 read_int32(buffer, &offset, buffer_size);
1903 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1904 header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1905 header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1906 header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1907 header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1908 header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1909 header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1910 header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1914 //printf("read_quicktime_markers 1 %d\n", marker_count);
1917 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1920 bzero(&header, sizeof(qt_hdr_t) * 2);
1922 read_quicktime_markers(buffer, buffer_size, header);
1923 return header[0].next_offset;
1926 long mjpeg_get_avi_field2(unsigned char *buffer,
1928 int *field_dominance)
1930 avi_hdr_t header[2];
1931 bzero(&header, sizeof(avi_hdr_t) * 2);
1932 read_avi_markers(buffer, buffer_size, header);
1934 *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1936 // One version of McRoweSoft only allows field polarity while
1937 // another version allows field size.
1938 if(header[0].field_size)
1940 return header[0].field_size;
1944 return mjpeg_get_field2(buffer, buffer_size);
1949 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1951 int total_fields = 0;
1952 long field2_offset = 0;
1955 for(i = 0; i < buffer_size; i++)
1957 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1961 if(total_fields == 2) break;
1964 return field2_offset;
1967 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1974 *h = (data[offset + 3] << 8) | (data[offset + 4]);
1975 *w = (data[offset + 5] << 8) | (data[offset + 6]);