r717: Made the highlighted text color of the menus WHITE
[cinelerra_cv/mob.git] / quicktime / libmjpeg.c
blobddfabdaa5a84e871f0583c5cf812317a8ad95f99
1 /*
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.
6 *
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
15 * USA
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include "colormodels.h"
21 #include "libmjpeg.h"
23 /* JPEG MARKERS */
24 #define M_SOF0 0xc0
25 #define M_SOF1 0xc1
26 #define M_SOF2 0xc2
27 #define M_SOF3 0xc3
28 #define M_SOF5 0xc5
29 #define M_SOF6 0xc6
30 #define M_SOF7 0xc7
31 #define M_JPG 0xc8
32 #define M_SOF9 0xc9
33 #define M_SOF10 0xca
34 #define M_SOF11 0xcb
35 #define M_SOF13 0xcd
36 #define M_SOF14 0xce
37 #define M_SOF15 0xcf
38 #define M_DHT 0xc4
39 #define M_DAC 0xcc
40 #define M_RST0 0xd0
41 #define M_RST1 0xd1
42 #define M_RST2 0xd2
43 #define M_RST3 0xd3
44 #define M_RST4 0xd4
45 #define M_RST5 0xd5
46 #define M_RST6 0xd6
47 #define M_RST7 0xd7
48 #define M_SOI 0xd8
49 #define M_EOI 0xd9
50 #define M_SOS 0xda
51 #define M_DQT 0xdb
52 #define M_DNL 0xdc
53 #define M_DRI 0xdd
54 #define M_DHP 0xde
55 #define M_EXP 0xdf
56 #define M_APP0 0xe0
57 #define M_APP1 0xe1
58 #define M_APP2 0xe2
59 #define M_APP3 0xe3
60 #define M_APP4 0xe4
61 #define M_APP5 0xe5
62 #define M_APP6 0xe6
63 #define M_APP7 0xe7
64 #define M_APP8 0xe8
65 #define M_APP9 0xe9
66 #define M_APP10 0xea
67 #define M_APP11 0xeb
68 #define M_APP12 0xec
69 #define M_APP13 0xed
70 #define M_APP14 0xee
71 #define M_APP15 0xef
72 #define M_JPG0 0xf0
73 #define M_JPG13 0xfd
74 #define M_COM 0xfe
75 #define M_TEM 0x01
76 #define M_ERROR 0x100
78 #define QUICKTIME_MARKER_SIZE 0x2c
79 #define AVI_MARKER_SIZE 0x12
80 #define QUICKTIME_JPEG_TAG 0x6d6a7067
81 #define QUICKTIME_AVI_TAG 0x41564931
84 METHODDEF(void) mjpeg_error_exit (j_common_ptr cinfo)
86 /* cinfo->err really points to a mjpeg_error_mgr struct, so coerce pointer */
87 mjpeg_error_ptr mjpegerr = (mjpeg_error_ptr) cinfo->err;
89 /* Always display the message. */
90 /* We could postpone this until after returning, if we chose. */
91 (*cinfo->err->output_message) (cinfo);
93 /* Return control to the setjmp point */
94 longjmp(mjpegerr->setjmp_buffer, 1);
97 typedef struct
99 struct jpeg_destination_mgr pub; /* public fields */
101 JOCTET *buffer; /* Pointer to buffer */
102 mjpeg_compressor *engine;
103 } mjpeg_destination_mgr;
105 typedef mjpeg_destination_mgr *mjpeg_dest_ptr;
109 * Initialize destination --- called by jpeg_start_compress
110 * before any data is actually written.
113 METHODDEF(void) init_destination(j_compress_ptr cinfo)
115 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
117 /* Set the pointer to the preallocated buffer */
118 if(!dest->engine->output_buffer)
120 dest->engine->output_buffer = calloc(1, 65536);
121 dest->engine->output_allocated = 65536;
123 dest->buffer = dest->engine->output_buffer;
124 dest->pub.next_output_byte = dest->engine->output_buffer;
125 dest->pub.free_in_buffer = dest->engine->output_allocated;
129 * Empty the output buffer --- called whenever buffer fills up.
131 * In typical applications, this should write the entire output buffer
132 * (ignoring the current state of next_output_byte & free_in_buffer),
133 * reset the pointer & count to the start of the buffer, and return TRUE
134 * indicating that the buffer has been dumped.
136 * In applications that need to be able to suspend compression due to output
137 * overrun, a FALSE return indicates that the buffer cannot be emptied now.
138 * In this situation, the compressor will return to its caller (possibly with
139 * an indication that it has not accepted all the supplied scanlines). The
140 * application should resume compression after it has made more room in the
141 * output buffer. Note that there are substantial restrictions on the use of
142 * suspension --- see the documentation.
144 * When suspending, the compressor will back up to a convenient restart point
145 * (typically the start of the current MCU). next_output_byte & free_in_buffer
146 * indicate where the restart point will be if the current call returns FALSE.
147 * Data beyond this point will be regenerated after resumption, so do not
148 * write it out when emptying the buffer externally.
151 METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
153 /* Allocate a bigger buffer. */
154 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
156 dest->engine->output_size = dest->engine->output_allocated;
157 dest->engine->output_allocated *= 2;
158 dest->engine->output_buffer = realloc(dest->engine->output_buffer,
159 dest->engine->output_allocated);
160 dest->buffer = dest->engine->output_buffer;
161 dest->pub.next_output_byte = dest->buffer + dest->engine->output_size;
162 dest->pub.free_in_buffer = dest->engine->output_allocated - dest->engine->output_size;
164 return TRUE;
168 * Terminate destination --- called by jpeg_finish_compress
169 * after all data has been written. Usually needs to flush buffer.
171 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
172 * application must deal with any cleanup that should happen even
173 * for error exit.
175 METHODDEF(void) term_destination(j_compress_ptr cinfo)
177 /* Just get the length */
178 mjpeg_dest_ptr dest = (mjpeg_dest_ptr)cinfo->dest;
179 dest->engine->output_size = dest->engine->output_allocated - dest->pub.free_in_buffer;
182 GLOBAL(void) jpeg_buffer_dest(j_compress_ptr cinfo, mjpeg_compressor *engine)
184 mjpeg_dest_ptr dest;
186 /* The destination object is made permanent so that multiple JPEG images
187 * can be written to the same file without re-executing jpeg_stdio_dest.
188 * This makes it dangerous to use this manager and a different destination
189 * manager serially with the same JPEG object, because their private object
190 * sizes may be different. Caveat programmer.
192 if(cinfo->dest == NULL)
194 /* first time for this JPEG object? */
195 cinfo->dest = (struct jpeg_destination_mgr *)
196 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
197 JPOOL_PERMANENT,
198 sizeof(mjpeg_destination_mgr));
201 dest = (mjpeg_dest_ptr)cinfo->dest;
202 dest->pub.init_destination = init_destination;
203 dest->pub.empty_output_buffer = empty_output_buffer;
204 dest->pub.term_destination = term_destination;
205 dest->engine = engine;
221 typedef struct {
222 struct jpeg_source_mgr pub; /* public fields */
224 JOCTET * buffer; /* start of buffer */
225 int bytes; /* total size of buffer */
226 } mjpeg_source_mgr;
228 typedef mjpeg_source_mgr* mjpeg_src_ptr;
230 METHODDEF(void) init_source(j_decompress_ptr cinfo)
232 mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
235 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr cinfo)
237 mjpeg_src_ptr src = (mjpeg_src_ptr) cinfo->src;
239 src->buffer[0] = (JOCTET)0xFF;
240 src->buffer[1] = (JOCTET)M_EOI;
241 src->pub.next_input_byte = src->buffer;
242 src->pub.bytes_in_buffer = 2;
244 return TRUE;
248 METHODDEF(void) skip_input_data(j_decompress_ptr cinfo, long num_bytes)
250 mjpeg_src_ptr src = (mjpeg_src_ptr)cinfo->src;
252 src->pub.next_input_byte += (size_t)num_bytes;
253 src->pub.bytes_in_buffer -= (size_t)num_bytes;
257 METHODDEF(void) term_source(j_decompress_ptr cinfo)
261 GLOBAL(void) jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long bytes)
263 mjpeg_src_ptr src;
265 /* first time for this JPEG object? */
266 if(cinfo->src == NULL)
268 cinfo->src = (struct jpeg_source_mgr*)
269 (*cinfo->mem->alloc_small)((j_common_ptr)cinfo,
270 JPOOL_PERMANENT,
271 sizeof(mjpeg_source_mgr));
272 src = (mjpeg_src_ptr)cinfo->src;
275 src = (mjpeg_src_ptr)cinfo->src;
276 src->pub.init_source = init_source;
277 src->pub.fill_input_buffer = fill_input_buffer;
278 src->pub.skip_input_data = skip_input_data;
279 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
280 src->pub.term_source = term_source;
281 src->pub.bytes_in_buffer = bytes;
282 src->pub.next_input_byte = buffer;
283 src->buffer = buffer;
284 src->bytes = bytes;
302 static void reset_buffer(unsigned char **buffer, long *size, long *allocated)
304 *size = 0;
307 static void delete_buffer(unsigned char **buffer, long *size, long *allocated)
309 if(*buffer)
311 free(*buffer);
312 *size = 0;
313 *allocated = 0;
317 static void append_buffer(unsigned char **buffer,
318 long *size,
319 long *allocated,
320 unsigned char *data,
321 long data_size)
323 if(!*buffer)
325 *buffer = calloc(1, 65536);
326 *size = 0;
327 *allocated = 65536;
330 if(*size + data_size + 0x100 > *allocated)
332 *allocated = *size + data_size + 0x100;
333 *buffer = realloc(*buffer, *allocated);
336 memcpy(*buffer + *size, data, data_size);
337 *size += data_size;
340 static void allocate_temps(mjpeg_t *mjpeg)
342 int i;
344 if(!mjpeg->temp_data)
346 switch(mjpeg->jpeg_color_model)
348 case BC_YUV422P:
349 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h * 2);
350 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
351 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
352 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
353 for(i = 0; i < mjpeg->coded_h; i++)
355 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
356 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w / 2;
357 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;
359 break;
361 case BC_YUV444P:
362 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h * 3);
363 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
364 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
365 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
366 if(mjpeg->greyscale)
368 memset(mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h,
369 0x80,
370 mjpeg->coded_w * mjpeg->coded_h * 2);
372 for(i = 0; i < mjpeg->coded_h; i++)
374 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
375 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
376 mjpeg->temp_rows[2][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h + i * mjpeg->coded_w;
378 break;
380 case BC_YUV420P:
381 mjpeg->temp_data = calloc(1, mjpeg->coded_w * mjpeg->coded_h + mjpeg->coded_w * mjpeg->coded_h / 2);
382 mjpeg->temp_rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
383 mjpeg->temp_rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
384 mjpeg->temp_rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
385 for(i = 0; i < mjpeg->coded_h; i++)
387 mjpeg->temp_rows[0][i] = mjpeg->temp_data + i * mjpeg->coded_w;
388 if(i < mjpeg->coded_h / 2)
390 mjpeg->temp_rows[1][i] = mjpeg->temp_data + mjpeg->coded_w * mjpeg->coded_h + i * (mjpeg->coded_w / 2);
391 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);
394 break;
399 static int get_input_row(mjpeg_t *mjpeg, mjpeg_compressor *compressor, int i)
401 int input_row;
402 if(mjpeg->fields > 1)
403 input_row = i * 2 + compressor->instance;
404 else
405 input_row = i;
406 if(input_row >= mjpeg->coded_h) input_row = mjpeg->coded_h - 1;
407 return input_row;
410 // Get pointers to rows for the JPEG compressor
411 static void get_rows(mjpeg_t *mjpeg, mjpeg_compressor *compressor)
413 int i;
414 switch(mjpeg->jpeg_color_model)
416 case BC_YUV444P:
418 if(!compressor->rows[0])
420 compressor->rows[0] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
421 compressor->rows[1] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
422 compressor->rows[2] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
425 // User colormodel matches jpeg colormodel
426 if(mjpeg->color_model == BC_YUV444P &&
427 mjpeg->output_w == mjpeg->coded_w &&
428 mjpeg->output_h == mjpeg->coded_h)
430 for(i = 0; i < compressor->coded_field_h; i++)
432 int input_row = get_input_row(mjpeg, compressor, i);
433 compressor->rows[0][i] = mjpeg->y_argument +
434 mjpeg->coded_w * input_row;
435 compressor->rows[1][i] = mjpeg->u_argument +
436 mjpeg->coded_w * input_row;
437 compressor->rows[2][i] = mjpeg->v_argument +
438 mjpeg->coded_w * input_row;
441 else
443 for(i = 0; i < compressor->coded_field_h; i++)
445 int input_row = get_input_row(mjpeg, compressor, i);
446 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
447 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
448 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
451 break;
454 case BC_YUV422P:
456 if(!compressor->rows[0])
458 compressor->rows[0] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
459 compressor->rows[1] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
460 compressor->rows[2] = calloc(1, sizeof(unsigned char*) * compressor->coded_field_h);
463 // User colormodel matches jpeg colormodel
464 if(mjpeg->color_model == BC_YUV422P &&
465 mjpeg->output_w == mjpeg->coded_w &&
466 mjpeg->output_h == mjpeg->coded_h)
468 for(i = 0; i < compressor->coded_field_h; i++)
470 int input_row = get_input_row(mjpeg, compressor, i);
471 compressor->rows[0][i] = mjpeg->y_argument +
472 mjpeg->coded_w * input_row;
473 compressor->rows[1][i] = mjpeg->u_argument +
474 (mjpeg->coded_w / 2) * input_row;
475 compressor->rows[2][i] = mjpeg->v_argument +
476 (mjpeg->coded_w / 2) * input_row;
479 else
481 for(i = 0; i < compressor->coded_field_h; i++)
483 int input_row = get_input_row(mjpeg, compressor, i);
484 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
485 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
486 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
489 break;
492 case BC_YUV420P:
494 if(!compressor->rows[0])
496 compressor->rows[0] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h);
497 compressor->rows[1] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
498 compressor->rows[2] = calloc(1, sizeof(unsigned char*) * mjpeg->coded_h / 2);
501 // User colormodel matches jpeg colormodel
502 if(mjpeg->color_model == BC_YUV420P &&
503 mjpeg->output_w == mjpeg->coded_w &&
504 mjpeg->output_h == mjpeg->coded_h)
506 for(i = 0; i < compressor->coded_field_h; i++)
508 int input_row = get_input_row(mjpeg, compressor, i);
509 compressor->rows[0][i] = mjpeg->y_argument +
510 mjpeg->coded_w * input_row;
511 if(i < compressor->coded_field_h / 2)
513 compressor->rows[1][i] = mjpeg->u_argument +
514 (mjpeg->coded_w / 2) * input_row;
515 compressor->rows[2][i] = mjpeg->v_argument +
516 (mjpeg->coded_w / 2) * input_row;
520 else
522 for(i = 0; i < compressor->coded_field_h; i++)
524 int input_row = get_input_row(mjpeg, compressor, i);
525 compressor->rows[0][i] = mjpeg->temp_rows[0][input_row];
526 if(i < compressor->coded_field_h / 2)
528 compressor->rows[1][i] = mjpeg->temp_rows[1][input_row];
529 compressor->rows[2][i] = mjpeg->temp_rows[2][input_row];
533 break;
538 static void delete_rows(mjpeg_compressor *compressor)
540 if(compressor->rows[0])
542 free(compressor->rows[0]);
543 free(compressor->rows[1]);
544 free(compressor->rows[2]);
549 static void new_jpeg_objects(mjpeg_compressor *engine)
551 engine->jpeg_decompress.err = jpeg_std_error(&(engine->jpeg_error.pub));
552 engine->jpeg_error.pub.error_exit = mjpeg_error_exit;
553 /* Ideally the error handler would be set here but it must be called in a thread */
554 jpeg_create_decompress(&(engine->jpeg_decompress));
555 engine->jpeg_decompress.raw_data_out = TRUE;
556 engine->jpeg_decompress.dct_method = JDCT_IFAST;
559 static void delete_jpeg_objects(mjpeg_compressor *engine)
561 jpeg_destroy_decompress(&(engine->jpeg_decompress));
566 static void unlock_compress_loop(mjpeg_compressor *engine)
568 pthread_mutex_unlock(&(engine->input_lock));
571 static void lock_compress_loop(mjpeg_compressor *engine)
573 pthread_mutex_lock(&(engine->output_lock));
576 // Make temp rows for compressor
577 static void get_mcu_rows(mjpeg_t *mjpeg,
578 mjpeg_compressor *engine,
579 int start_row)
581 int i, j, scanline;
582 for(i = 0; i < 3; i++)
584 for(j = 0; j < 16; j++)
586 if(i > 0 && j >= 8 && mjpeg->jpeg_color_model == BC_YUV420P) break;
588 scanline = start_row;
589 if(i > 0 && mjpeg->jpeg_color_model == BC_YUV420P) scanline /= 2;
590 scanline += j;
591 if(scanline >= engine->coded_field_h) scanline = engine->coded_field_h - 1;
592 engine->mcu_rows[i][j] = engine->rows[i][scanline];
598 static void decompress_field(mjpeg_compressor *engine)
600 mjpeg_t *mjpeg = engine->mjpeg;
601 long buffer_offset = engine->instance * mjpeg->input_field2;
602 unsigned char *buffer = mjpeg->input_data + buffer_offset;
603 long buffer_size;
604 int i, j;
606 //printf("decompress_field %02x%02x %d\n", buffer[0], buffer[1], engine->instance * mjpeg->input_field2);
607 if(engine->instance == 0 && mjpeg->fields > 1)
608 buffer_size = mjpeg->input_field2 - buffer_offset;
609 else
610 buffer_size = mjpeg->input_size - buffer_offset;
612 mjpeg->error = 0;
614 if(setjmp(engine->jpeg_error.setjmp_buffer))
616 /* If we get here, the JPEG code has signaled an error. */
617 delete_jpeg_objects(engine);
618 new_jpeg_objects(engine);
619 mjpeg->error = 1;
620 //printf("decompress_field 1\n");
621 goto finish;
624 //printf("decompress_field 2\n");
625 jpeg_buffer_src(&engine->jpeg_decompress,
626 buffer,
627 buffer_size);
628 jpeg_read_header(&engine->jpeg_decompress, TRUE);
630 // Reset by jpeg_read_header
631 engine->jpeg_decompress.raw_data_out = TRUE;
632 jpeg_start_decompress(&engine->jpeg_decompress);
634 // Generate colormodel from jpeg sampling
635 if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 2 &&
636 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
637 mjpeg->jpeg_color_model = BC_YUV420P;
638 else
639 if(engine->jpeg_decompress.comp_info[0].v_samp_factor == 1 &&
640 engine->jpeg_decompress.comp_info[0].h_samp_factor == 2)
641 mjpeg->jpeg_color_model = BC_YUV422P;
642 else
643 mjpeg->jpeg_color_model = BC_YUV444P;
645 if(engine->jpeg_decompress.jpeg_color_space == JCS_GRAYSCALE)
646 mjpeg->greyscale = 1;
648 //printf("%d %d\n", engine->jpeg_decompress.comp_info[0].h_samp_factor, engine->jpeg_decompress.comp_info[0].v_samp_factor);
649 // Must be here because the color model isn't known until now
650 pthread_mutex_lock(&(mjpeg->decompress_init));
651 allocate_temps(mjpeg);
652 pthread_mutex_unlock(&(mjpeg->decompress_init));
653 get_rows(mjpeg, engine);
656 while(engine->jpeg_decompress.output_scanline < engine->jpeg_decompress.output_height)
658 get_mcu_rows(mjpeg, engine, engine->jpeg_decompress.output_scanline);
659 jpeg_read_raw_data(&engine->jpeg_decompress,
660 engine->mcu_rows,
661 engine->coded_field_h);
663 jpeg_finish_decompress(&engine->jpeg_decompress);
666 finish:
670 void mjpeg_decompress_loop(mjpeg_compressor *engine)
672 while(!engine->done)
674 pthread_mutex_lock(&engine->input_lock);
675 if(!engine->done)
677 decompress_field(engine);
679 pthread_mutex_unlock(&(engine->output_lock));
684 static void compress_field(mjpeg_compressor *engine)
686 int i, j;
687 mjpeg_t *mjpeg = engine->mjpeg;
689 //printf("compress_field 1\n");
690 get_rows(engine->mjpeg, engine);
691 reset_buffer(&engine->output_buffer, &engine->output_size, &engine->output_allocated);
692 jpeg_buffer_dest(&engine->jpeg_compress, engine);
695 engine->jpeg_compress.raw_data_in = TRUE;
696 jpeg_start_compress(&engine->jpeg_compress, TRUE);
698 while(engine->jpeg_compress.next_scanline < engine->jpeg_compress.image_height)
700 get_mcu_rows(mjpeg, engine, engine->jpeg_compress.next_scanline);
702 jpeg_write_raw_data(&engine->jpeg_compress,
703 engine->mcu_rows,
704 engine->coded_field_h);
706 jpeg_finish_compress(&engine->jpeg_compress);
707 //printf("compress_field 2\n");
711 void mjpeg_compress_loop(mjpeg_compressor *engine)
713 while(!engine->done)
715 pthread_mutex_lock(&engine->input_lock);
716 if(!engine->done)
718 compress_field(engine);
720 pthread_mutex_unlock(&engine->output_lock);
724 static void delete_temps(mjpeg_t *mjpeg)
726 if(mjpeg->temp_data)
728 free(mjpeg->temp_data);
729 free(mjpeg->temp_rows[0]);
730 free(mjpeg->temp_rows[1]);
731 free(mjpeg->temp_rows[2]);
735 mjpeg_compressor* mjpeg_new_decompressor(mjpeg_t *mjpeg, int instance)
737 mjpeg_compressor *result = calloc(1, sizeof(mjpeg_compressor));
738 pthread_attr_t attr;
739 struct sched_param param;
740 pthread_mutexattr_t mutex_attr;
741 int i;
743 result->mjpeg = mjpeg;
744 result->instance = instance;
745 new_jpeg_objects(result);
746 result->field_h = mjpeg->output_h / mjpeg->fields;
747 result->coded_field_h = (result->field_h % 16) ?
748 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
750 result->mcu_rows[0] = malloc(16 * sizeof(unsigned char*));
751 result->mcu_rows[1] = malloc(16 * sizeof(unsigned char*));
752 result->mcu_rows[2] = malloc(16 * sizeof(unsigned char*));
754 pthread_mutexattr_init(&mutex_attr);
755 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
756 pthread_mutex_init(&(result->input_lock), &mutex_attr);
757 pthread_mutex_lock(&(result->input_lock));
758 pthread_mutex_init(&(result->output_lock), &mutex_attr);
759 pthread_mutex_lock(&(result->output_lock));
761 pthread_attr_init(&attr);
762 pthread_create(&(result->tid), &attr, (void*)mjpeg_decompress_loop, result);
764 return result;
767 void mjpeg_delete_decompressor(mjpeg_compressor *engine)
769 engine->done = 1;
770 pthread_mutex_unlock(&(engine->input_lock));
771 pthread_join(engine->tid, 0);
772 pthread_mutex_destroy(&(engine->input_lock));
773 pthread_mutex_destroy(&(engine->output_lock));
774 jpeg_destroy_decompress(&(engine->jpeg_decompress));
775 delete_rows(engine);
776 free(engine->mcu_rows[0]);
777 free(engine->mcu_rows[1]);
778 free(engine->mcu_rows[2]);
779 free(engine);
782 mjpeg_compressor* mjpeg_new_compressor(mjpeg_t *mjpeg, int instance)
784 pthread_attr_t attr;
785 struct sched_param param;
786 pthread_mutexattr_t mutex_attr;
787 mjpeg_compressor *result = calloc(1, sizeof(mjpeg_compressor));
789 result->field_h = mjpeg->output_h / mjpeg->fields;
790 result->coded_field_h = (result->field_h % 16) ?
791 result->field_h + (16 - (result->field_h % 16)) : result->field_h;
792 result->mjpeg = mjpeg;
793 result->instance = instance;
794 result->jpeg_compress.err = jpeg_std_error(&(result->jpeg_error.pub));
795 jpeg_create_compress(&(result->jpeg_compress));
796 result->jpeg_compress.image_width = mjpeg->output_w;
797 result->jpeg_compress.image_height = result->field_h;
798 result->jpeg_compress.input_components = 3;
799 result->jpeg_compress.in_color_space = JCS_RGB;
800 jpeg_set_defaults(&(result->jpeg_compress));
801 result->jpeg_compress.input_components = 3;
802 result->jpeg_compress.in_color_space = JCS_RGB;
803 jpeg_set_quality(&(result->jpeg_compress), mjpeg->quality, 0);
805 if(mjpeg->use_float)
806 result->jpeg_compress.dct_method = JDCT_FLOAT;
807 else
808 result->jpeg_compress.dct_method = JDCT_IFAST;
809 // result->jpeg_compress.dct_method = JDCT_ISLOW;
811 /* Fix sampling */
812 switch(mjpeg->fields)
814 case 1:
815 mjpeg->jpeg_color_model = BC_YUV420P;
816 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
817 result->jpeg_compress.comp_info[0].v_samp_factor = 2;
818 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
819 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
820 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
821 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
822 break;
823 case 2:
824 mjpeg->jpeg_color_model = BC_YUV422P;
825 result->jpeg_compress.comp_info[0].h_samp_factor = 2;
826 result->jpeg_compress.comp_info[0].v_samp_factor = 1;
827 result->jpeg_compress.comp_info[1].h_samp_factor = 1;
828 result->jpeg_compress.comp_info[1].v_samp_factor = 1;
829 result->jpeg_compress.comp_info[2].h_samp_factor = 1;
830 result->jpeg_compress.comp_info[2].v_samp_factor = 1;
831 break;
833 allocate_temps(mjpeg);
835 result->mcu_rows[0] = malloc(16 * sizeof(unsigned char*));
836 result->mcu_rows[1] = malloc(16 * sizeof(unsigned char*));
837 result->mcu_rows[2] = malloc(16 * sizeof(unsigned char*));
839 pthread_mutexattr_init(&mutex_attr);
840 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
841 pthread_mutex_init(&(result->input_lock), &mutex_attr);
842 pthread_mutex_lock(&(result->input_lock));
843 pthread_mutex_init(&(result->output_lock), &mutex_attr);
844 pthread_mutex_lock(&(result->output_lock));
846 pthread_attr_init(&attr);
847 pthread_create(&(result->tid), &attr, (void*)mjpeg_compress_loop, result);
848 return result;
852 void mjpeg_delete_compressor(mjpeg_compressor *engine)
854 engine->done = 1;
855 pthread_mutex_unlock(&(engine->input_lock));
856 pthread_join(engine->tid, 0);
857 pthread_mutex_destroy(&(engine->input_lock));
858 pthread_mutex_destroy(&(engine->output_lock));
859 jpeg_destroy((j_common_ptr)&(engine->jpeg_compress));
860 if(engine->output_buffer) free(engine->output_buffer);
861 delete_rows(engine);
862 free(engine->mcu_rows[0]);
863 free(engine->mcu_rows[1]);
864 free(engine->mcu_rows[2]);
865 free(engine);
868 unsigned char* mjpeg_output_buffer(mjpeg_t *mjpeg)
870 return mjpeg->output_data;
873 long mjpeg_output_field2(mjpeg_t *mjpeg)
875 return mjpeg->output_field2;
878 long mjpeg_output_size(mjpeg_t *mjpeg)
880 return mjpeg->output_size;
883 long mjpeg_output_allocated(mjpeg_t *mjpeg)
885 return mjpeg->output_allocated;
888 void mjpeg_set_output_size(mjpeg_t *mjpeg, long output_size)
890 mjpeg->output_size = output_size;
894 int mjpeg_compress(mjpeg_t *mjpeg,
895 unsigned char **row_pointers,
896 unsigned char *y_plane,
897 unsigned char *u_plane,
898 unsigned char *v_plane,
899 int color_model,
900 int cpus)
902 int i, result = 0;
903 int corrected_fields = mjpeg->fields;
904 mjpeg->color_model = color_model;
905 mjpeg->cpus = cpus;
907 //printf("mjpeg_compress 1 %d\n", color_model);
908 /* Reset output buffer */
909 reset_buffer(&mjpeg->output_data,
910 &mjpeg->output_size,
911 &mjpeg->output_allocated);
913 /* Create compression engines as needed */
914 for(i = 0; i < mjpeg->fields; i++)
916 if(!mjpeg->compressors[i])
918 mjpeg->compressors[i] = mjpeg_new_compressor(mjpeg, i);
922 /* Arm YUV buffers */
923 mjpeg->row_argument = row_pointers;
924 mjpeg->y_argument = y_plane;
925 mjpeg->u_argument = u_plane;
926 mjpeg->v_argument = v_plane;
927 // User colormodel doesn't match encoder colormodel
928 // Copy to interlacing buffer first
929 if(mjpeg->color_model != mjpeg->jpeg_color_model ||
930 mjpeg->output_w != mjpeg->coded_w ||
931 mjpeg->output_h != mjpeg->coded_h)
934 * printf("mjpeg_compress %d %d %d %d\n",
935 * mjpeg->output_w, mjpeg->output_h, mjpeg->coded_w, mjpeg->coded_h);
937 cmodel_transfer(0,
938 row_pointers,
939 mjpeg->temp_rows[0][0],
940 mjpeg->temp_rows[1][0],
941 mjpeg->temp_rows[2][0],
942 y_plane,
943 u_plane,
944 v_plane,
947 mjpeg->output_w,
948 mjpeg->output_h,
951 mjpeg->output_w,
952 mjpeg->output_h,
953 mjpeg->color_model,
954 mjpeg->jpeg_color_model,
956 mjpeg->output_w,
957 mjpeg->coded_w);
960 /* Start the compressors on the image fields */
961 if(mjpeg->deinterlace) corrected_fields = 1;
962 for(i = 0; i < corrected_fields && !result; i++)
964 unlock_compress_loop(mjpeg->compressors[i]);
966 if(mjpeg->cpus < 2 && i < corrected_fields - 1)
968 lock_compress_loop(mjpeg->compressors[i]);
972 /* Wait for the compressors and store in master output */
973 for(i = 0; i < corrected_fields && !result; i++)
975 if(mjpeg->cpus > 1 || i == corrected_fields - 1)
977 lock_compress_loop(mjpeg->compressors[i]);
980 append_buffer(&mjpeg->output_data,
981 &mjpeg->output_size,
982 &mjpeg->output_allocated,
983 mjpeg->compressors[i]->output_buffer,
984 mjpeg->compressors[i]->output_size);
985 if(i == 0) mjpeg->output_field2 = mjpeg->output_size;
988 if(corrected_fields < mjpeg->fields)
990 append_buffer(&mjpeg->output_data,
991 &mjpeg->output_size,
992 &mjpeg->output_allocated,
993 mjpeg->compressors[0]->output_buffer,
994 mjpeg->compressors[0]->output_size);
996 //printf("mjpeg_compress 2\n");
997 return 0;
1002 int mjpeg_decompress(mjpeg_t *mjpeg,
1003 unsigned char *buffer,
1004 long buffer_len,
1005 long input_field2,
1006 unsigned char **row_pointers,
1007 unsigned char *y_plane,
1008 unsigned char *u_plane,
1009 unsigned char *v_plane,
1010 int color_model,
1011 int cpus)
1013 int i, result = 0;
1014 int got_first_thread = 0;
1016 //printf("mjpeg_decompress 1 %d %d\n", buffer_len, input_field2);
1017 if(buffer_len == 0) return 1;
1018 if(input_field2 == 0 && mjpeg->fields > 1) return 1;
1020 //printf("mjpeg_decompress 2\n");
1021 /* Create decompression engines as needed */
1022 for(i = 0; i < mjpeg->fields; i++)
1024 if(!mjpeg->decompressors[i])
1026 mjpeg->decompressors[i] = mjpeg_new_decompressor(mjpeg, i);
1030 //printf("mjpeg_decompress 3\n");
1031 /* Arm YUV buffers */
1032 mjpeg->row_argument = row_pointers;
1033 mjpeg->y_argument = y_plane;
1034 mjpeg->u_argument = u_plane;
1035 mjpeg->v_argument = v_plane;
1036 mjpeg->input_data = buffer;
1037 mjpeg->input_size = buffer_len;
1038 mjpeg->input_field2 = input_field2;
1039 mjpeg->color_model = color_model;
1040 mjpeg->cpus = cpus;
1042 //printf("mjpeg_decompress 4 %02x %02x %d %02x %02x\n", buffer[0], buffer[1], input_field2, buffer[input_field2], buffer[input_field2 + 1]);
1043 /* Start decompressors */
1044 for(i = 0; i < mjpeg->fields && !result; i++)
1046 unlock_compress_loop(mjpeg->decompressors[i]);
1048 // For dual CPUs, don't want second thread to start until temp data is allocated by the first.
1049 // For single CPUs, don't want two threads running simultaneously
1050 if(mjpeg->cpus < 2 || !mjpeg->temp_data)
1052 lock_compress_loop(mjpeg->decompressors[i]);
1053 if(i == 0) got_first_thread = 1;
1057 //printf("mjpeg_decompress 5\n");
1058 /* Wait for decompressors */
1059 for(i = 0; i < mjpeg->fields && !result; i++)
1061 if(mjpeg->cpus > 1)
1063 if(i > 0 || !got_first_thread)
1064 lock_compress_loop(mjpeg->decompressors[i]);
1067 //printf("mjpeg_decompress 6\n");
1069 /* Convert colormodel */
1070 // User colormodel didn't match decompressor
1072 * if(!mjpeg->error &&
1073 * (mjpeg->jpeg_color_model != mjpeg->color_model ||
1074 * mjpeg->coded_w != mjpeg->output_w ||
1075 * mjpeg->coded_h != mjpeg->output_h))
1078 if((mjpeg->jpeg_color_model != mjpeg->color_model ||
1079 mjpeg->coded_w != mjpeg->output_w ||
1080 mjpeg->coded_h != mjpeg->output_h)
1082 (mjpeg->temp_data ||
1083 !mjpeg->error))
1085 unsigned char *y_in = mjpeg->temp_rows[0][0];
1086 unsigned char *u_in = mjpeg->temp_rows[1][0];
1087 unsigned char *v_in = mjpeg->temp_rows[2][0];
1089 //printf("mjpeg_decompress 7 %p\n", row_pointers);
1090 cmodel_transfer(row_pointers,
1092 y_plane,
1093 u_plane,
1094 v_plane,
1095 y_in,
1096 u_in,
1097 v_in,
1100 mjpeg->output_w,
1101 mjpeg->output_h,
1104 mjpeg->output_w,
1105 mjpeg->output_h,
1106 mjpeg->jpeg_color_model,
1107 mjpeg->color_model,
1109 mjpeg->coded_w,
1110 mjpeg->rowspan ? mjpeg->rowspan : mjpeg->output_w);
1111 //printf("mjpeg_decompress 8\n");
1113 return 0;
1117 void mjpeg_set_deinterlace(mjpeg_t *mjpeg, int value)
1119 mjpeg->deinterlace = value;
1122 void mjpeg_set_quality(mjpeg_t *mjpeg, int quality)
1124 mjpeg->quality = quality;
1127 void mjpeg_set_float(mjpeg_t *mjpeg, int use_float)
1129 mjpeg->use_float = use_float;
1132 void mjpeg_set_cpus(mjpeg_t *mjpeg, int cpus)
1134 mjpeg->cpus = cpus;
1137 void mjpeg_set_rowspan(mjpeg_t *mjpeg, int rowspan)
1139 mjpeg->rowspan = rowspan;
1142 int mjpeg_get_fields(mjpeg_t *mjpeg)
1144 return mjpeg->fields;
1148 mjpeg_t* mjpeg_new(int w,
1149 int h,
1150 int fields)
1152 mjpeg_t *result = calloc(1, sizeof(mjpeg_t));
1153 pthread_mutexattr_t mutex_attr;
1154 int i;
1156 result->output_w = w;
1157 result->output_h = h;
1158 result->fields = fields;
1159 result->color_model = BC_RGB888;
1160 result->cpus = 1;
1161 result->quality = 80;
1162 result->use_float = 0;
1164 pthread_mutexattr_init(&mutex_attr);
1165 // pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP);
1166 pthread_mutex_init(&(result->decompress_init), &mutex_attr);
1169 // Calculate coded dimensions
1170 // An interlaced frame with 4:2:0 sampling must be a multiple of 32
1172 result->coded_w = (w % 16) ? w + (16 - (w % 16)) : w;
1174 if(fields == 1)
1175 result->coded_h = (h % 16) ? h + (16 - (h % 16)) : h;
1176 else
1177 result->coded_h = (h % 32) ? h + (32 - (h % 32)) : h;
1181 //printf("mjpeg_new %d %d %d %d\n", result->output_w, result->output_h, result->coded_w, result->coded_h);
1182 return result;
1188 void mjpeg_delete(mjpeg_t *mjpeg)
1190 int i;
1191 //printf("mjpeg_delete 1\n");
1192 for(i = 0; i < mjpeg->fields; i++)
1194 //printf("mjpeg_delete 2\n");
1195 if(mjpeg->compressors[i]) mjpeg_delete_compressor(mjpeg->compressors[i]);
1196 //printf("mjpeg_delete 3\n");
1197 if(mjpeg->decompressors[i]) mjpeg_delete_decompressor(mjpeg->decompressors[i]);
1198 //printf("mjpeg_delete 4\n");
1200 //printf("mjpeg_delete 5\n");
1201 delete_temps(mjpeg);
1202 //printf("mjpeg_delete 6\n");
1203 delete_buffer(&mjpeg->output_data, &mjpeg->output_size, &mjpeg->output_allocated);
1204 //printf("mjpeg_delete 7\n");
1205 free(mjpeg);
1206 //printf("mjpeg_delete 2\n");
1210 /* Open up a space to insert a marker */
1211 static void insert_space(unsigned char **buffer,
1212 long *buffer_size,
1213 long *buffer_allocated,
1214 long space_start,
1215 long space_len)
1217 int in, out;
1218 // Make sure enough space is available
1219 if(*buffer_allocated - *buffer_size < space_len)
1221 *buffer_allocated += space_len;
1222 *buffer = realloc(*buffer, *buffer_allocated);
1225 // Shift data back
1226 for(in = *buffer_size - 1, out = *buffer_size - 1 + space_len;
1227 in >= space_start;
1228 in--, out--)
1230 (*buffer)[out] = (*buffer)[in];
1232 *buffer_size += space_len;
1236 static inline int nextbyte(unsigned char *data, long *offset, long length)
1238 if(length - *offset < 1) return 0;
1239 *offset += 1;
1240 return (unsigned char)data[*offset - 1];
1243 static inline int read_int32(unsigned char *data, long *offset, long length)
1245 if(length - *offset < 4)
1247 *offset = length;
1248 return 0;
1250 *offset += 4;
1251 return ((((unsigned int)data[*offset - 4]) << 24) |
1252 (((unsigned int)data[*offset - 3]) << 16) |
1253 (((unsigned int)data[*offset - 2]) << 8) |
1254 (((unsigned int)data[*offset - 1])));
1257 static inline int read_int16(unsigned char *data, long *offset, long length)
1259 if(length - *offset < 2)
1261 *offset = length;
1262 return 0;
1265 *offset += 2;
1266 return ((((unsigned int)data[*offset - 2]) << 8) |
1267 (((unsigned int)data[*offset - 1])));
1270 static inline unsigned char read_char(unsigned char *data, long *offset, long length)
1272 if(length - *offset < 1)
1274 *offset = length;
1275 return 0;
1278 *offset += 1;
1279 return (unsigned char)data[*offset - 1];
1282 static inline int next_int16(unsigned char *data, long *offset, long length)
1284 if(length - *offset < 2)
1286 return 0;
1289 return ((((unsigned int)data[*offset]) << 8) |
1290 (((unsigned int)data[*offset + 1])));
1293 static inline void write_int32(unsigned char *data, long *offset, long length, unsigned int value)
1295 if(length - *offset < 4)
1297 *offset = length;
1298 return;
1302 data[(*offset)++] = (unsigned int)(value & 0xff000000) >> 24;
1303 data[(*offset)++] = (unsigned int)(value & 0xff0000) >> 16;
1304 data[(*offset)++] = (unsigned int)(value & 0xff00) >> 8;
1305 data[(*offset)++] = (unsigned char)(value & 0xff);
1306 return;
1309 static inline void write_char(unsigned char *data, long *offset, long length, unsigned char value)
1311 if(length - *offset < 1)
1313 *offset = length;
1314 return;
1317 data[(*offset)++] = value;
1318 return;
1321 static int next_marker(unsigned char *buffer, long *offset, long buffer_size)
1323 int c, done = 0; /* 1 - completion 2 - error */
1325 while(*offset < buffer_size - 1)
1327 if(buffer[*offset] == 0xff && buffer[*offset + 1] != 0xff)
1329 (*offset) += 2;
1330 return buffer[*offset - 1];
1333 (*offset)++;
1336 return 0;
1340 /* Find the next marker after offset and return 0 on success */
1341 static int find_marker(unsigned char *buffer,
1342 long *offset,
1343 long buffer_size,
1344 unsigned long marker_type)
1346 long result = 0;
1347 long marker_len;
1349 while(!result && *offset < buffer_size - 1)
1351 int marker = next_marker(buffer, offset, buffer_size);
1352 if(marker == (marker_type & 0xff)) result = 1;
1355 return !result;
1359 typedef struct
1361 int field_size;
1362 int padded_field_size;
1363 int next_offset;
1364 int quant_offset;
1365 int huffman_offset;
1366 int image_offset;
1367 int scan_offset;
1368 int data_offset;
1369 } qt_hdr_t;
1371 typedef struct
1373 int field_number;
1374 int field_size;
1375 int unpadded_field_size;
1376 } avi_hdr_t;
1378 #define LML_MARKER_SIZE 0x2c
1379 #define LML_MARKER_TAG 0xffe3
1380 void insert_lml33_markers(unsigned char **buffer,
1381 long *field2_offset,
1382 long *buffer_size,
1383 long *buffer_allocated)
1385 long marker_offset = -1;
1386 int marker_exists;
1388 /* Search for existing marker to replace */
1389 // marker_offset = find_marker(*buffer, *buffer_size, LML_MARKER_TAG);
1391 /* Insert new marker */
1392 if(marker_offset < 0)
1394 marker_offset = 2;
1395 insert_space(buffer,
1396 buffer_size,
1397 buffer_allocated,
1399 LML_MARKER_SIZE);
1403 static int qt_table_offsets(unsigned char *buffer,
1404 long buffer_size,
1405 qt_hdr_t *header)
1407 int done = 0;
1408 long offset = 0;
1409 int marker = 0;
1410 int field = 0;
1411 int len;
1412 int result = 0;
1414 bzero(header, sizeof(qt_hdr_t) * 2);
1416 // Read every marker to get the offsets for the headers
1417 for(field = 0; field < 2; field++)
1419 done = 0;
1421 while(!done)
1423 marker = next_marker(buffer,
1424 &offset,
1425 buffer_size);
1427 len = 0;
1429 switch(marker)
1431 case M_SOI:
1432 // The first field may be padded
1433 if(field > 0)
1435 header[0].next_offset =
1436 header[0].padded_field_size =
1437 offset - 2;
1439 len = 0;
1440 break;
1442 case M_APP1:
1443 // Quicktime marker already exists. Abort.
1444 if(buffer[offset + 6] == 'm' &&
1445 buffer[offset + 7] == 'j' &&
1446 buffer[offset + 8] == 'p' &&
1447 buffer[offset + 9] == 'a')
1449 result = 1;
1450 done = 1;
1452 break;
1454 case M_DQT:
1455 if(!header[field].quant_offset)
1457 header[field].quant_offset = offset - 2;
1458 if(field > 0)
1459 header[field].quant_offset -= header[0].next_offset;
1461 len = read_int16(buffer, &offset, buffer_size);
1462 len -= 2;
1463 break;
1465 case M_DHT:
1466 if(!header[field].huffman_offset)
1468 header[field].huffman_offset = offset - 2;
1469 if(field > 0)
1470 header[field].huffman_offset -= header[0].next_offset;
1472 len = read_int16(buffer, &offset, buffer_size);
1473 len -= 2;
1474 break;
1476 case M_SOF0:
1477 if(!header[field].image_offset)
1479 header[field].image_offset = offset - 2;
1480 if(field > 0)
1481 header[field].image_offset -= header[0].next_offset;
1483 len = read_int16(buffer, &offset, buffer_size);
1484 len -= 2;
1485 break;
1487 case M_SOS:
1488 header[field].scan_offset = offset - 2;
1489 if(field > 0)
1490 header[field].scan_offset -= header[0].next_offset;
1491 len = read_int16(buffer, &offset, buffer_size);
1492 len -= 2;
1493 header[field].data_offset = offset + len;
1494 if(field > 0)
1495 header[field].data_offset -= header[0].next_offset;
1496 break;
1498 // case 0:
1499 case M_EOI:
1500 if(field > 0)
1502 header[field].field_size =
1503 header[field].padded_field_size =
1504 offset - header[0].next_offset;
1505 header[field].next_offset = 0;
1507 else
1509 // Often misses second SOI but gets first EOI
1510 // header[0].next_offset =
1511 // header[0].padded_field_size =
1512 // offset;
1514 //printf("table_offsets M_EOI %d %x\n", field, offset);
1515 done = 1;
1516 len = 0;
1517 break;
1519 default:
1520 // Junk appears between fields
1521 len = 0;
1522 // len = read_int16(buffer, &offset, buffer_size);
1523 // len -= 2;
1524 break;
1527 if(!done) offset += len;
1528 if(offset >= buffer_size) done = 1;
1530 //printf("qt_table_offsets 10 %d\n", field);
1533 return result;
1536 static void insert_quicktime_marker(unsigned char *buffer,
1537 long buffer_size,
1538 long offset,
1539 qt_hdr_t *header)
1541 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1542 ((unsigned long)M_APP1 << 16) |
1543 (QUICKTIME_MARKER_SIZE - 2));
1544 write_int32(buffer, &offset, buffer_size, 0);
1545 write_int32(buffer, &offset, buffer_size, QUICKTIME_JPEG_TAG);
1546 write_int32(buffer, &offset, buffer_size, header->field_size);
1547 write_int32(buffer, &offset, buffer_size, header->padded_field_size);
1548 write_int32(buffer, &offset, buffer_size, header->next_offset);
1549 write_int32(buffer, &offset, buffer_size, header->quant_offset);
1550 write_int32(buffer, &offset, buffer_size, header->huffman_offset);
1551 write_int32(buffer, &offset, buffer_size, header->image_offset);
1552 write_int32(buffer, &offset, buffer_size, header->scan_offset);
1553 write_int32(buffer, &offset, buffer_size, header->data_offset);
1557 void mjpeg_insert_quicktime_markers(unsigned char **buffer,
1558 long *buffer_size,
1559 long *buffer_allocated,
1560 int fields,
1561 long *field2_offset)
1563 qt_hdr_t header[2];
1564 long offset = 0;
1565 int exists = 0;
1566 *field2_offset = -1;
1568 if(fields < 2) return;
1571 // Get offsets for tables in both fields
1572 exists = qt_table_offsets(*buffer, *buffer_size, header);
1574 // APP1 for quicktime already exists
1575 if(exists) return;
1577 //printf("mjpeg_insert_quicktime_markers %x %02x %02x\n",
1578 // header[0].next_offset, (*buffer)[*field2_offset], (*buffer)[*field2_offset + 1]);
1579 //if(*field2_offset == 0)
1580 // fwrite(*buffer, *buffer_size, 1, stdout);
1584 header[0].field_size += QUICKTIME_MARKER_SIZE;
1585 header[0].padded_field_size += QUICKTIME_MARKER_SIZE;
1586 header[0].next_offset += QUICKTIME_MARKER_SIZE;
1587 header[0].quant_offset += QUICKTIME_MARKER_SIZE;
1588 header[0].huffman_offset += QUICKTIME_MARKER_SIZE;
1589 header[0].image_offset += QUICKTIME_MARKER_SIZE;
1590 header[0].scan_offset += QUICKTIME_MARKER_SIZE;
1591 header[0].data_offset += QUICKTIME_MARKER_SIZE;
1592 header[1].field_size += QUICKTIME_MARKER_SIZE;
1593 header[1].padded_field_size += QUICKTIME_MARKER_SIZE;
1594 header[1].quant_offset += QUICKTIME_MARKER_SIZE;
1595 header[1].huffman_offset += QUICKTIME_MARKER_SIZE;
1596 header[1].image_offset += QUICKTIME_MARKER_SIZE;
1597 header[1].scan_offset += QUICKTIME_MARKER_SIZE;
1598 header[1].data_offset += QUICKTIME_MARKER_SIZE;
1599 *field2_offset = header[0].next_offset;
1603 // Insert APP1 marker
1604 insert_space(buffer,
1605 buffer_size,
1606 buffer_allocated,
1608 QUICKTIME_MARKER_SIZE);
1610 insert_quicktime_marker(*buffer,
1611 *buffer_size,
1613 &header[0]);
1615 insert_space(buffer,
1616 buffer_size,
1617 buffer_allocated,
1618 header[0].next_offset + 2,
1619 QUICKTIME_MARKER_SIZE);
1621 header[1].next_offset = 0;
1622 insert_quicktime_marker(*buffer,
1623 *buffer_size,
1624 header[0].next_offset + 2,
1625 &header[1]);
1629 static int avi_table_offsets(unsigned char *buffer,
1630 long buffer_size,
1631 avi_hdr_t *header)
1633 int field2 = mjpeg_get_field2(buffer, buffer_size);
1635 header[0].field_number = 1;
1636 header[0].field_size = field2;
1637 header[0].unpadded_field_size = field2;
1639 header[1].field_number = 2;
1640 header[1].field_size = buffer_size - field2;
1641 header[1].unpadded_field_size = buffer_size - field2;
1642 return 0;
1645 static void insert_avi_marker(unsigned char *buffer,
1646 long buffer_size,
1647 long offset,
1648 avi_hdr_t *header)
1650 write_int32(buffer, &offset, buffer_size, 0xff000000 |
1651 ((unsigned long)M_APP0 << 16) |
1652 (AVI_MARKER_SIZE - 2));
1653 write_int32(buffer, &offset, buffer_size, QUICKTIME_AVI_TAG);
1655 // One version of McRoweSoft only allows field polarity while
1656 // another version allows field size.
1657 write_char(buffer, &offset, buffer_size, header->field_number);
1658 write_char(buffer, &offset, buffer_size, 0);
1659 write_int32(buffer, &offset, buffer_size, header->field_size);
1660 write_int32(buffer, &offset, buffer_size, header->unpadded_field_size);
1663 void mjpeg_insert_avi_markers(unsigned char **buffer,
1664 long *buffer_size,
1665 long *buffer_allocated,
1666 int fields,
1667 long *field2_offset)
1669 avi_hdr_t header[2];
1670 long offset = 0;
1671 *field2_offset = -1;
1674 // Test for existing marker
1675 if(!find_marker(*buffer, &offset, *buffer_size, M_APP0))
1677 if((*buffer)[offset + 2] == 'A' &&
1678 (*buffer)[offset + 3] == 'V' &&
1679 (*buffer)[offset + 4] == 'I' &&
1680 (*buffer)[offset + 5] == '1')
1681 return;
1685 avi_table_offsets(*buffer, *buffer_size, header);
1687 header[0].field_size += AVI_MARKER_SIZE;
1688 header[0].unpadded_field_size += AVI_MARKER_SIZE;
1689 header[1].field_size += AVI_MARKER_SIZE;
1690 header[1].unpadded_field_size += AVI_MARKER_SIZE;
1691 *field2_offset = header[0].field_size;
1693 // Insert APP0 marker into field 1
1694 insert_space(buffer,
1695 buffer_size,
1696 buffer_allocated,
1698 AVI_MARKER_SIZE);
1699 insert_avi_marker(*buffer,
1700 *buffer_size,
1702 &header[0]);
1704 insert_space(buffer,
1705 buffer_size,
1706 buffer_allocated,
1707 *field2_offset + 2,
1708 AVI_MARKER_SIZE);
1709 insert_avi_marker(*buffer,
1710 *buffer_size,
1711 *field2_offset + 2,
1712 &header[1]);
1719 static void read_avi_markers(unsigned char *buffer,
1720 long buffer_size,
1721 avi_hdr_t *header)
1723 long offset = 0;
1724 int marker_count = 0;
1725 int result = 0;
1726 int marker_size = 0;
1727 while(marker_count < 2 && offset < buffer_size && !result)
1729 result = find_marker(buffer,
1730 &offset,
1731 buffer_size,
1732 M_APP0);
1733 marker_size = ((unsigned char)buffer[offset] << 8) | (unsigned char)buffer[offset];
1736 if(!result && marker_size >= 16)
1738 // Marker size, AVI1
1739 offset += 6;
1740 // field polarity
1741 header[marker_count].field_number = read_char(buffer, &offset, buffer_size);
1742 read_char(buffer, &offset, buffer_size);
1743 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1744 header[marker_count].unpadded_field_size = read_int32(buffer, &offset, buffer_size);
1745 marker_count++;
1751 static void read_quicktime_markers(unsigned char *buffer,
1752 long buffer_size,
1753 qt_hdr_t *header)
1755 long offset = 0;
1756 int marker_count = 0;
1757 int result = 0;
1759 while(marker_count < 2 && offset < buffer_size && !result)
1761 result = find_marker(buffer,
1762 &offset,
1763 buffer_size,
1764 M_APP1);
1766 if(!result)
1768 // Marker size
1769 read_int16(buffer, &offset, buffer_size);
1770 // Zero
1771 read_int32(buffer, &offset, buffer_size);
1772 // MJPA
1773 read_int32(buffer, &offset, buffer_size);
1774 // Information
1775 header[marker_count].field_size = read_int32(buffer, &offset, buffer_size);
1776 header[marker_count].padded_field_size = read_int32(buffer, &offset, buffer_size);
1777 header[marker_count].next_offset = read_int32(buffer, &offset, buffer_size);
1778 header[marker_count].quant_offset = read_int32(buffer, &offset, buffer_size);
1779 header[marker_count].huffman_offset = read_int32(buffer, &offset, buffer_size);
1780 header[marker_count].image_offset = read_int32(buffer, &offset, buffer_size);
1781 header[marker_count].scan_offset = read_int32(buffer, &offset, buffer_size);
1782 header[marker_count].data_offset = read_int32(buffer, &offset, buffer_size);
1783 marker_count++;
1786 //printf("read_quicktime_markers 1 %d\n", marker_count);
1789 long mjpeg_get_quicktime_field2(unsigned char *buffer, long buffer_size)
1791 qt_hdr_t header[2];
1792 bzero(&header, sizeof(qt_hdr_t) * 2);
1794 read_quicktime_markers(buffer, buffer_size, header);
1795 return header[0].next_offset;
1798 long mjpeg_get_avi_field2(unsigned char *buffer,
1799 long buffer_size,
1800 int *field_dominance)
1802 avi_hdr_t header[2];
1803 bzero(&header, sizeof(avi_hdr_t) * 2);
1804 read_avi_markers(buffer, buffer_size, header);
1806 *field_dominance = (header[0].field_number == 1) ? 1 : 2;
1808 // One version of McRoweSoft only allows field polarity while
1809 // another version allows field size.
1810 if(header[0].field_size)
1812 return header[0].field_size;
1814 else
1816 return mjpeg_get_field2(buffer, buffer_size);
1818 return 0;
1821 long mjpeg_get_field2(unsigned char *buffer, long buffer_size)
1823 long result = 0;
1824 int total_fields = 0;
1825 long offset = 0;
1826 long field2_offset = 0;
1827 int i;
1829 for(i = 0; i < buffer_size; i++)
1831 if(buffer[i] == 0xff && buffer[i + 1] == M_SOI)
1833 total_fields++;
1834 field2_offset = i;
1835 if(total_fields == 2) break;
1840 return field2_offset;
1843 void mjpeg_video_size(unsigned char *data, long data_size, int *w, int *h)
1845 long offset = 0;
1846 find_marker(data,
1847 &offset,
1848 data_size,
1849 M_SOF0);
1850 *h = (data[offset + 3] << 8) | (data[offset + 4]);
1851 *w = (data[offset + 5] << 8) | (data[offset + 6]);