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
20 #include "colormodels.h"
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);
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
;
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
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
)
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
,
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
;
222 struct jpeg_source_mgr pub
; /* public fields */
224 JOCTET
* buffer
; /* start of buffer */
225 int bytes
; /* total size of buffer */
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;
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
)
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
,
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
;
302 static void reset_buffer(unsigned char **buffer
, long *size
, long *allocated
)
307 static void delete_buffer(unsigned char **buffer
, long *size
, long *allocated
)
317 static void append_buffer(unsigned char **buffer
,
325 *buffer
= calloc(1, 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
);
340 static void allocate_temps(mjpeg_t
*mjpeg
)
344 if(!mjpeg
->temp_data
)
346 switch(mjpeg
->jpeg_color_model
)
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;
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
);
368 memset(mjpeg
->temp_data
+ mjpeg
->coded_w
* mjpeg
->coded_h
,
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
;
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);
399 static int get_input_row(mjpeg_t
*mjpeg
, mjpeg_compressor
*compressor
, int i
)
402 if(mjpeg
->fields
> 1)
403 input_row
= i
* 2 + compressor
->instance
;
406 if(input_row
>= mjpeg
->coded_h
) input_row
= mjpeg
->coded_h
- 1;
410 // Get pointers to rows for the JPEG compressor
411 static void get_rows(mjpeg_t
*mjpeg
, mjpeg_compressor
*compressor
)
414 switch(mjpeg
->jpeg_color_model
)
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
;
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
];
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
;
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
];
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
;
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
];
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
,
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;
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
;
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
;
610 buffer_size
= mjpeg
->input_size
- buffer_offset
;
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
);
620 //printf("decompress_field 1\n");
624 //printf("decompress_field 2\n");
625 jpeg_buffer_src(&engine
->jpeg_decompress
,
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
;
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
;
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
,
661 engine
->coded_field_h
);
663 jpeg_finish_decompress(&engine
->jpeg_decompress
);
670 void mjpeg_decompress_loop(mjpeg_compressor
*engine
)
674 pthread_mutex_lock(&engine
->input_lock
);
677 decompress_field(engine
);
679 pthread_mutex_unlock(&(engine
->output_lock
));
684 static void compress_field(mjpeg_compressor
*engine
)
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
,
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
)
715 pthread_mutex_lock(&engine
->input_lock
);
718 compress_field(engine
);
720 pthread_mutex_unlock(&engine
->output_lock
);
724 static void delete_temps(mjpeg_t
*mjpeg
)
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
));
739 struct sched_param param
;
740 pthread_mutexattr_t mutex_attr
;
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
);
767 void mjpeg_delete_decompressor(mjpeg_compressor
*engine
)
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
));
776 free(engine
->mcu_rows
[0]);
777 free(engine
->mcu_rows
[1]);
778 free(engine
->mcu_rows
[2]);
782 mjpeg_compressor
* mjpeg_new_compressor(mjpeg_t
*mjpeg
, int instance
)
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);
806 result
->jpeg_compress
.dct_method
= JDCT_FLOAT
;
808 result
->jpeg_compress
.dct_method
= JDCT_IFAST
;
809 // result->jpeg_compress.dct_method = JDCT_ISLOW;
812 switch(mjpeg
->fields
)
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;
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;
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
);
852 void mjpeg_delete_compressor(mjpeg_compressor
*engine
)
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
);
862 free(engine
->mcu_rows
[0]);
863 free(engine
->mcu_rows
[1]);
864 free(engine
->mcu_rows
[2]);
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
,
903 int corrected_fields
= mjpeg
->fields
;
904 mjpeg
->color_model
= color_model
;
907 //printf("mjpeg_compress 1 %d\n", color_model);
908 /* Reset output buffer */
909 reset_buffer(&mjpeg
->output_data
,
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);
939 mjpeg
->temp_rows
[0][0],
940 mjpeg
->temp_rows
[1][0],
941 mjpeg
->temp_rows
[2][0],
954 mjpeg
->jpeg_color_model
,
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
,
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
,
992 &mjpeg
->output_allocated
,
993 mjpeg
->compressors
[0]->output_buffer
,
994 mjpeg
->compressors
[0]->output_size
);
996 //printf("mjpeg_compress 2\n");
1002 int mjpeg_decompress(mjpeg_t
*mjpeg
,
1003 unsigned char *buffer
,
1006 unsigned char **row_pointers
,
1007 unsigned char *y_plane
,
1008 unsigned char *u_plane
,
1009 unsigned char *v_plane
,
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
;
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
++)
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
||
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
,
1106 mjpeg
->jpeg_color_model
,
1110 mjpeg
->rowspan
? mjpeg
->rowspan
: mjpeg
->output_w
);
1111 //printf("mjpeg_decompress 8\n");
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
)
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
,
1152 mjpeg_t
*result
= calloc(1, sizeof(mjpeg_t
));
1153 pthread_mutexattr_t mutex_attr
;
1156 result
->output_w
= w
;
1157 result
->output_h
= h
;
1158 result
->fields
= fields
;
1159 result
->color_model
= BC_RGB888
;
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
;
1175 result
->coded_h
= (h
% 16) ? h
+ (16 - (h
% 16)) : h
;
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);
1188 void mjpeg_delete(mjpeg_t
*mjpeg
)
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");
1206 //printf("mjpeg_delete 2\n");
1210 /* Open up a space to insert a marker */
1211 static void insert_space(unsigned char **buffer
,
1213 long *buffer_allocated
,
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
);
1226 for(in
= *buffer_size
- 1, out
= *buffer_size
- 1 + space_len
;
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;
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)
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)
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)
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)
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)
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);
1309 static inline void write_char(unsigned char *data
, long *offset
, long length
, unsigned char value
)
1311 if(length
- *offset
< 1)
1317 data
[(*offset
)++] = value
;
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)
1330 return buffer
[*offset
- 1];
1340 /* Find the next marker after offset and return 0 on success */
1341 static int find_marker(unsigned char *buffer
,
1344 unsigned long marker_type
)
1349 while(!result
&& *offset
< buffer_size
- 1)
1351 int marker
= next_marker(buffer
, offset
, buffer_size
);
1352 if(marker
== (marker_type
& 0xff)) result
= 1;
1362 int padded_field_size
;
1375 int unpadded_field_size
;
1378 #define LML_MARKER_SIZE 0x2c
1379 #define LML_MARKER_TAG 0xffe3
1380 void insert_lml33_markers(unsigned char **buffer
,
1381 long *field2_offset
,
1383 long *buffer_allocated
)
1385 long marker_offset
= -1;
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)
1395 insert_space(buffer
,
1403 static int qt_table_offsets(unsigned char *buffer
,
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
++)
1423 marker
= next_marker(buffer
,
1432 // The first field may be padded
1435 header
[0].next_offset
=
1436 header
[0].padded_field_size
=
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')
1455 if(!header
[field
].quant_offset
)
1457 header
[field
].quant_offset
= offset
- 2;
1459 header
[field
].quant_offset
-= header
[0].next_offset
;
1461 len
= read_int16(buffer
, &offset
, buffer_size
);
1466 if(!header
[field
].huffman_offset
)
1468 header
[field
].huffman_offset
= offset
- 2;
1470 header
[field
].huffman_offset
-= header
[0].next_offset
;
1472 len
= read_int16(buffer
, &offset
, buffer_size
);
1477 if(!header
[field
].image_offset
)
1479 header
[field
].image_offset
= offset
- 2;
1481 header
[field
].image_offset
-= header
[0].next_offset
;
1483 len
= read_int16(buffer
, &offset
, buffer_size
);
1488 header
[field
].scan_offset
= offset
- 2;
1490 header
[field
].scan_offset
-= header
[0].next_offset
;
1491 len
= read_int16(buffer
, &offset
, buffer_size
);
1493 header
[field
].data_offset
= offset
+ len
;
1495 header
[field
].data_offset
-= header
[0].next_offset
;
1502 header
[field
].field_size
=
1503 header
[field
].padded_field_size
=
1504 offset
- header
[0].next_offset
;
1505 header
[field
].next_offset
= 0;
1509 // Often misses second SOI but gets first EOI
1510 // header[0].next_offset =
1511 // header[0].padded_field_size =
1514 //printf("table_offsets M_EOI %d %x\n", field, offset);
1520 // Junk appears between fields
1522 // len = read_int16(buffer, &offset, buffer_size);
1527 if(!done
) offset
+= len
;
1528 if(offset
>= buffer_size
) done
= 1;
1530 //printf("qt_table_offsets 10 %d\n", field);
1536 static void insert_quicktime_marker(unsigned char *buffer
,
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
,
1559 long *buffer_allocated
,
1561 long *field2_offset
)
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
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
,
1608 QUICKTIME_MARKER_SIZE
);
1610 insert_quicktime_marker(*buffer
,
1615 insert_space(buffer
,
1618 header
[0].next_offset
+ 2,
1619 QUICKTIME_MARKER_SIZE
);
1621 header
[1].next_offset
= 0;
1622 insert_quicktime_marker(*buffer
,
1624 header
[0].next_offset
+ 2,
1629 static int avi_table_offsets(unsigned char *buffer
,
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
;
1645 static void insert_avi_marker(unsigned char *buffer
,
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
,
1665 long *buffer_allocated
,
1667 long *field2_offset
)
1669 avi_hdr_t header
[2];
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')
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
,
1699 insert_avi_marker(*buffer
,
1704 insert_space(buffer
,
1709 insert_avi_marker(*buffer
,
1719 static void read_avi_markers(unsigned char *buffer
,
1724 int marker_count
= 0;
1726 int marker_size
= 0;
1727 while(marker_count
< 2 && offset
< buffer_size
&& !result
)
1729 result
= find_marker(buffer
,
1733 marker_size
= ((unsigned char)buffer
[offset
] << 8) | (unsigned char)buffer
[offset
];
1736 if(!result
&& marker_size
>= 16)
1738 // Marker size, AVI1
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
);
1751 static void read_quicktime_markers(unsigned char *buffer
,
1756 int marker_count
= 0;
1759 while(marker_count
< 2 && offset
< buffer_size
&& !result
)
1761 result
= find_marker(buffer
,
1769 read_int16(buffer
, &offset
, buffer_size
);
1771 read_int32(buffer
, &offset
, buffer_size
);
1773 read_int32(buffer
, &offset
, buffer_size
);
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
);
1786 //printf("read_quicktime_markers 1 %d\n", marker_count);
1789 long mjpeg_get_quicktime_field2(unsigned char *buffer
, long buffer_size
)
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
,
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
;
1816 return mjpeg_get_field2(buffer
, buffer_size
);
1821 long mjpeg_get_field2(unsigned char *buffer
, long buffer_size
)
1824 int total_fields
= 0;
1826 long field2_offset
= 0;
1829 for(i
= 0; i
< buffer_size
; i
++)
1831 if(buffer
[i
] == 0xff && buffer
[i
+ 1] == M_SOI
)
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
)
1850 *h
= (data
[offset
+ 3] << 8) | (data
[offset
+ 4]);
1851 *w
= (data
[offset
+ 5] << 8) | (data
[offset
+ 6]);