60 /* Buffer and error handling from jpeg-6b examples */
63 my_error_exit (j_common_ptr cinfo
)
65 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
66 my_error_ptr myerr
= (my_error_ptr
) cinfo
->err
;
68 /* Always display the message. */
69 /* We could postpone this until after returning, if we chose. */
70 (*cinfo
->err
->output_message
) (cinfo
);
72 /* Return control to the setjmp point */
73 longjmp(myerr
->setjmp_buffer
, 1);
76 void quicktime_jpeg_delete_compress_engine(mjpa_compress_engine
*compressor
)
78 jpeg_destroy((j_common_ptr
)&(compressor
->jpeg_compress
));
79 if(compressor
->output_buffer
)
80 free(compressor
->output_buffer
);
85 void quicktime_endcompressor_jpeg(mjpa_compress_engine
*engine
)
88 pthread_mutex_unlock(&(engine
->input_lock
));
89 pthread_join(engine
->tid
, 0);
90 pthread_mutex_destroy(&(engine
->input_lock
));
91 pthread_mutex_destroy(&(engine
->output_lock
));
94 static int quicktime_delete_codec_jpeg(quicktime_video_map_t
*vtrack
)
96 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
99 for(i
= 0; i
< codec
->total_compressors
; i
++)
101 if(codec
->compressors
[i
])
103 quicktime_endcompressor_jpeg(codec
->compressors
[i
]);
104 quicktime_jpeg_delete_compress_engine(codec
->compressors
[i
]);
105 codec
->compressors
[i
] = 0;
108 if(codec
->decompressors
[i
])
110 quicktime_enddecompressor_jpeg(codec
->decompressors
[i
]);
111 jpeg_destroy_decompress(&(codec
->decompressors
[i
]->jpeg_decompress
));
113 free(codec
->decompressors
[i
]);
114 codec
->decompressors
[i
] = 0;
117 if(codec
->input_buffer
)
118 free(codec
->input_buffer
);
123 static inline int quicktime_read_int32_jpeg(char **data
, int *length
)
125 if(*length
< 4) return 0;
128 return (int)((((unsigned char)(*data
)[-4]) << 24) |
129 (((unsigned char)(*data
)[-3]) << 16) |
130 (((unsigned char)(*data
)[-2]) << 8) |
131 (((unsigned char)(*data
)[-1])));
134 static inline int quicktime_write_int32_jpeg(char **data
, int *length
, int value
)
136 if(*length
< 4) return 0;
139 *(*data
)++ = (unsigned int)(value
& 0xff000000) >> 24;
140 *(*data
)++ = (unsigned int)(value
& 0xff0000) >> 16;
141 *(*data
)++ = (unsigned int)(value
& 0xff00) >> 8;
142 *(*data
)++ = (unsigned char)(value
& 0xff);
146 static inline int quicktime_read_int16_jpeg(char **data
, int *length
)
148 if(*length
< 2) return 0;
151 return (((int16_t)((unsigned char)(*data
)[-2]) << 8) |
152 ((unsigned char)(*data
)[-1]));
155 static inline int quicktime_readbyte_jpeg(char **data
, int *length
)
157 if(*length
< 1) return 0;
160 return (unsigned char)(*data
)[-1];
163 int quicktime_read_markers_jpeg(quicktime_mjpeg_hdr
*mjpeg_hdr
, struct jpeg_decompress_struct
*jpeg_decompress
)
168 jpeg_saved_marker_ptr marker_ptr
;
171 marker_ptr
= jpeg_decompress
->marker_list
;
173 while((marker_ptr
|| !jpeg_decompress
) && !done
)
175 if((marker_ptr
&& marker_ptr
->marker
== JPEG_APP0
+ 1) || !jpeg_decompress
)
179 length
= marker_ptr
->data_length
;
180 data
= marker_ptr
->data
;
184 length
= QUICKTIME_JPEG_MARKSIZE
;
185 data
= mjpeg_hdr
->mjpeg_marker
;
188 quicktime_read_int32_jpeg(&data
, &length
);
189 quicktime_read_int32_jpeg(&data
, &length
);
190 mjpeg_hdr
->field_size
= quicktime_read_int32_jpeg(&data
, &length
);
191 mjpeg_hdr
->padded_field_size
= quicktime_read_int32_jpeg(&data
, &length
);
192 mjpeg_hdr
->next_offset
= quicktime_read_int32_jpeg(&data
, &length
);
193 mjpeg_hdr
->quant_offset
= quicktime_read_int32_jpeg(&data
, &length
);
194 mjpeg_hdr
->huffman_offset
= quicktime_read_int32_jpeg(&data
, &length
);
195 mjpeg_hdr
->image_offset
= quicktime_read_int32_jpeg(&data
, &length
);
196 mjpeg_hdr
->scan_offset
= quicktime_read_int32_jpeg(&data
, &length
);
197 mjpeg_hdr
->data_offset
= quicktime_read_int32_jpeg(&data
, &length
);
198 /* printf("%x %x %x %x %x %x %x %x\n", mjpeg_hdr->field_size, */
199 /* mjpeg_hdr->padded_field_size, */
200 /* mjpeg_hdr->next_offset, */
201 /* mjpeg_hdr->quant_offset, */
202 /* mjpeg_hdr->huffman_offset, */
203 /* mjpeg_hdr->image_offset, */
204 /* mjpeg_hdr->scan_offset, */
205 /* mjpeg_hdr->data_offset); */
208 if(marker_ptr
) marker_ptr
= marker_ptr
->next
;
213 static inline void quicktime_skipmarker_jpeg(char **buffer_ptr
, int *buffer_size
, int *len
)
219 *buffer_size
-= *len
;
223 int quicktime_getmarker_jpeg(char **buffer_ptr
, int *buffer_size
, int *len
)
225 int c
, done
= 0; /* 1 - completion 2 - error */
227 while(!done
&& *buffer_size
> 0)
229 c
= quicktime_readbyte_jpeg(buffer_ptr
, buffer_size
);
231 while(!done
&& c
!= 0xFF)
233 if(!*buffer_size
) done
= 2;
234 c
= quicktime_readbyte_jpeg(buffer_ptr
, buffer_size
);
237 /* now we've got 1 0xFF, keep reading until not 0xFF */
240 if(!*buffer_size
) done
= 2;
241 c
= quicktime_readbyte_jpeg(buffer_ptr
, buffer_size
);
242 }while (!done
&& c
== 0xFF);
245 if (c
!= 0) done
= 1;
255 int quicktime_fixmarker_jpeg(quicktime_mjpeg_hdr
*mjpeg_hdr
, char *buffer
, long output_size
, int write_next_offset
)
257 char *buffer_ptr
= buffer
;
258 int buffer_size
= output_size
;
259 int done
= 0, offset
= 0, app1_offset
= 0;
263 mjpeg_hdr
->field_size
= 0;
264 mjpeg_hdr
->padded_field_size
= 0;
265 mjpeg_hdr
->next_offset
= 0;
266 mjpeg_hdr
->quant_offset
= 0;
267 mjpeg_hdr
->huffman_offset
= 0;
268 mjpeg_hdr
->image_offset
= 0;
269 mjpeg_hdr
->scan_offset
= 0;
270 mjpeg_hdr
->data_offset
= 0;
272 while(!done
&& buffer_size
> 0)
274 marker
= quicktime_getmarker_jpeg(&buffer_ptr
, &buffer_size
, &len
);
275 offset
= buffer_ptr
- buffer
- 1;
285 mjpeg_hdr
->huffman_offset
= offset
- 1;
286 len
= quicktime_read_int16_jpeg(&buffer_ptr
, &buffer_size
);
287 if(!mjpeg_hdr
->mjpg_kludge
)
292 mjpeg_hdr
->quant_offset
= offset
- 1;
293 len
= quicktime_read_int16_jpeg(&buffer_ptr
, &buffer_size
);
294 if(!mjpeg_hdr
->mjpg_kludge
)
299 mjpeg_hdr
->image_offset
= offset
- 1;
300 len
= quicktime_read_int16_jpeg(&buffer_ptr
, &buffer_size
);
301 if(!mjpeg_hdr
->mjpg_kludge
)
306 mjpeg_hdr
->scan_offset
= offset
- 1;
307 len
= quicktime_read_int16_jpeg(&buffer_ptr
, &buffer_size
);
308 if(!mjpeg_hdr
->mjpg_kludge
)
310 mjpeg_hdr
->data_offset
= offset
+ len
+ 3;
314 case (JPEG_APP0
+ 1):
315 app1_offset
= offset
+ 3;
316 len
= quicktime_read_int16_jpeg(&buffer_ptr
, &buffer_size
) - 2;
325 if(!done
) quicktime_skipmarker_jpeg(&buffer_ptr
, &buffer_size
, &len
);
328 mjpeg_hdr
->field_size
= mjpeg_hdr
->padded_field_size
= mjpeg_hdr
->next_offset
= output_size
;
329 buffer_ptr
= buffer
+ app1_offset
;
330 buffer_size
= output_size
- app1_offset
;
331 if(!write_next_offset
) mjpeg_hdr
->next_offset
= 0;
333 /* printf("%d %x %x %x %x %x %x %x %x \n", row_offset, mjpeg_hdr->field_size, */
334 /* mjpeg_hdr->padded_field_size, */
335 /* mjpeg_hdr->next_offset, */
336 /* mjpeg_hdr->quant_offset, */
337 /* mjpeg_hdr->huffman_offset, */
338 /* mjpeg_hdr->image_offset, */
339 /* mjpeg_hdr->scan_offset, */
340 /* mjpeg_hdr->data_offset); */
342 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, 0);
343 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, QUICKTIME_JPEG_TAG
);
344 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->field_size
);
345 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->padded_field_size
);
346 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->next_offset
);
347 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->quant_offset
);
348 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->huffman_offset
);
349 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->image_offset
);
350 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->scan_offset
);
351 quicktime_write_int32_jpeg(&buffer_ptr
, &buffer_size
, mjpeg_hdr
->data_offset
);
355 void quicktime_create_mjpa_objects(mjpa_decompress_engine
*engine
)
357 engine
->jpeg_decompress
.err
= jpeg_std_error(&(engine
->jpeg_error
.pub
));
358 engine
->jpeg_error
.pub
.error_exit
= my_error_exit
;
359 /* Ideally the error handler would be set here but it must be called in a thread */
360 jpeg_create_decompress(&(engine
->jpeg_decompress
));
363 void quicktime_delete_mjpa_objects(mjpa_decompress_engine
*engine
)
365 jpeg_destroy_decompress(&(engine
->jpeg_decompress
));
369 void quicktime_decompressor_jpeg(mjpa_decompress_engine
*engine
)
371 /* Run continuously */
372 unsigned char **interlaced_row
;
373 unsigned char **last_row
;
377 pthread_mutex_lock(&(engine
->input_lock
));
379 /* Image decompression core */
382 if(setjmp(engine
->jpeg_error
.setjmp_buffer
))
384 /* If we get here, the JPEG code has signaled an error. */
385 quicktime_delete_mjpa_objects(engine
);
386 quicktime_create_mjpa_objects(engine
);
390 jpeg_buffer_src(&(engine
->jpeg_decompress
), engine
->input_ptr
, engine
->input_size
);
391 if(engine
->markers_only
)
392 jpeg_save_markers(&(engine
->jpeg_decompress
), JPEG_APP0
+ 1, QUICKTIME_JPEG_MARKSIZE
);
394 jpeg_read_header(&(engine
->jpeg_decompress
), TRUE
);
396 /* printf("jpeg %d %d %d %d %d %d\n", */
397 /* engine->jpeg_decompress.comp_info[0].h_samp_factor, */
398 /* engine->jpeg_decompress.comp_info[0].v_samp_factor, */
399 /* engine->jpeg_decompress.comp_info[1].h_samp_factor, */
400 /* engine->jpeg_decompress.comp_info[1].v_samp_factor, */
401 /* engine->jpeg_decompress.comp_info[2].h_samp_factor, */
402 /* engine->jpeg_decompress.comp_info[2].v_samp_factor); */
404 if(engine
->markers_only
)
406 quicktime_read_markers_jpeg(&(engine
->mjpeg_hdr
), &(engine
->jpeg_decompress
));
407 engine
->field_offset
= engine
->mjpeg_hdr
.next_offset
;
408 pthread_mutex_unlock(&(engine
->output_lock
));
409 pthread_mutex_lock(&(engine
->input_lock
));
412 jpeg_start_decompress(&(engine
->jpeg_decompress
));
413 if(!engine
->interlaced
)
415 while(engine
->jpeg_decompress
.output_scanline
< engine
->jpeg_decompress
.output_height
)
417 jpeg_read_scanlines(&engine
->jpeg_decompress
,
418 (JSAMPROW
*)&engine
->row_pointers
[engine
->jpeg_decompress
.output_scanline
],
419 engine
->jpeg_decompress
.output_height
- engine
->jpeg_decompress
.output_scanline
);
424 interlaced_row
= engine
->row_pointers
;
425 last_row
= &(engine
->row_pointers
[engine
->height
]);
426 while(engine
->jpeg_decompress
.output_scanline
< engine
->jpeg_decompress
.output_height
&&
427 interlaced_row
< last_row
)
429 jpeg_read_scanlines(&(engine
->jpeg_decompress
),
430 (JSAMPROW
*)interlaced_row
,
436 jpeg_finish_decompress(&(engine
->jpeg_decompress
));
440 pthread_mutex_unlock(&(engine
->output_lock
));
444 int quicktime_startdecompressor_jpeg(mjpa_decompress_engine
*engine
)
447 struct sched_param param
;
448 pthread_mutexattr_t mutex_attr
;
450 pthread_mutexattr_init(&mutex_attr
);
451 pthread_mutex_init(&(engine
->input_lock
), &mutex_attr
);
452 pthread_mutex_lock(&(engine
->input_lock
));
453 pthread_mutex_init(&(engine
->output_lock
), &mutex_attr
);
454 pthread_mutex_lock(&(engine
->output_lock
));
456 pthread_attr_init(&attr
);
457 pthread_create(&(engine
->tid
), &attr
, (void*)quicktime_decompressor_jpeg
, engine
);
461 int quicktime_enddecompressor_jpeg(mjpa_decompress_engine
*engine
)
464 pthread_mutex_unlock(&(engine
->input_lock
));
465 pthread_join(engine
->tid
, 0);
466 pthread_mutex_destroy(&(engine
->input_lock
));
467 pthread_mutex_destroy(&(engine
->output_lock
));
471 int quicktime_decompressfield_jpeg(mjpa_decompress_engine
*engine
,
474 unsigned char **row_pointers
,
478 engine
->markers_only
= markers_only
;
479 engine
->row_pointers
= row_pointers
;
480 engine
->input_ptr
= input_ptr
;
481 engine
->input_size
= input_size
;
482 pthread_mutex_unlock(&(engine
->input_lock
));
486 int quicktime_decompresswait_jpeg(mjpa_decompress_engine
*engine
)
488 pthread_mutex_lock(&(engine
->output_lock
));
493 static int quicktime_decode_jpeg(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
497 long color_channels
, bytes
;
498 quicktime_trak_t
*trak
= file
->vtracks
[track
].track
;
499 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
500 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
501 int is_mjpa
= codec
->jpeg_type
== 1;
502 int is_mjpb
= codec
->jpeg_type
== 2;
503 int interlaced
= is_mjpa
|| is_mjpb
;
504 int row_offset
, field_offset
;
505 unsigned char **interlaced_row
, **last_row
;
506 int field_dominance
= trak
->mdia
.minf
.stbl
.stsd
.table
[0].field_dominance
;
509 int height
= (int)trak
->tkhd
.track_height
;
510 int width
= (int)trak
->tkhd
.track_width
;
512 /* Create decompression engines as needed */
513 for(i
= 0; i
< (interlaced
? TOTAL_MJPA_COMPRESSORS
: 1); i
++)
515 if(!codec
->decompressors
[i
])
517 codec
->decompressors
[i
] = malloc(sizeof(mjpa_decompress_engine
));
518 codec
->decompressors
[i
]->done
= 0;
519 quicktime_create_mjpa_objects(codec
->decompressors
[i
]);
520 codec
->decompressors
[i
]->is_mjpa
= is_mjpa
;
521 codec
->decompressors
[i
]->mjpeg_hdr
.mjpg_kludge
= 0;
522 codec
->decompressors
[i
]->interlaced
= interlaced
;
523 codec
->decompressors
[i
]->width
= width
;
524 codec
->decompressors
[i
]->height
= height
;
525 codec
->decompressors
[i
]->codec
= codec
;
526 quicktime_startdecompressor_jpeg(codec
->decompressors
[i
]);
527 codec
->total_decompressors
++;
531 /* Read the entire chunk from disk. */
533 quicktime_set_video_position(file
, vtrack
->current_position
, track
);
534 size
= quicktime_frame_size(file
, vtrack
->current_position
, track
);
535 if(size
> codec
->buffer_size
&& codec
->input_buffer
)
537 free(codec
->input_buffer
);
538 codec
->input_buffer
= 0;
540 if(!codec
->input_buffer
)
542 codec
->input_buffer
= malloc(size
);
543 codec
->buffer_size
= size
;
545 result
= quicktime_read_data(file
, codec
->input_buffer
, size
);
548 /* Start the decompressors */
549 if(field_dominance
>= 2 && interlaced
)
555 for(i
= 0; i
< (interlaced
? TOTAL_MJPA_COMPRESSORS
: 1) && !result
; i
++)
557 interlaced_row
= row_pointers
+ row_offset
;
559 if(i
> 0) size_remaining
= size
- field_offset
;
561 size_remaining
= size
;
563 quicktime_decompressfield_jpeg(codec
->decompressors
[i
],
564 codec
->input_buffer
+ field_offset
,
567 (interlaced
&& i
== 0),
570 if(interlaced
&& i
== 0)
572 /* Get field offset from first field */
573 quicktime_decompresswait_jpeg(codec
->decompressors
[i
]);
574 field_offset
= codec
->decompressors
[i
]->field_offset
;
575 quicktime_decompressfield_jpeg(codec
->decompressors
[i
],
583 /* Wait for decompressor completion on uniprocessor */
586 quicktime_decompresswait_jpeg(codec
->decompressors
[i
]);
592 /* Wait for decompressor completion */
593 for(i
= 0; i
< (interlaced
? TOTAL_MJPA_COMPRESSORS
: 1) && !result
&& file
->cpus
> 1; i
++)
595 quicktime_decompresswait_jpeg(codec
->decompressors
[i
]);
601 /* Compress a JPEG field */
602 unsigned char* quicktime_compress_jpeg(mjpa_compress_engine
*engine
,
603 unsigned char **row_pointers
,
605 int write_next_offset
)
607 unsigned char **interlaced_row
, **last_row
;
609 last_row
= &row_pointers
[engine
->height
- 1];
610 engine
->output_size
= 0;
611 jpeg_buffer_dest(&(engine
->jpeg_compress
), engine
);
613 /* Initialize interlaced output */
614 jpeg_start_compress(&(engine
->jpeg_compress
), TRUE
);
616 /* Write a fake MJPA marker */
619 jpeg_write_marker(&(engine
->jpeg_compress
),
621 engine
->mjpeg_hdr
.mjpeg_marker
,
622 QUICKTIME_JPEG_MARKSIZE
);
625 if(!engine
->interlaced
)
627 while(engine
->jpeg_compress
.next_scanline
< engine
->jpeg_compress
.image_height
)
629 jpeg_write_scanlines(&engine
->jpeg_compress
,
630 &(row_pointers
[engine
->jpeg_compress
.next_scanline
]),
631 engine
->jpeg_compress
.image_height
- engine
->jpeg_compress
.next_scanline
);
636 interlaced_row
= row_pointers
;
637 while(engine
->jpeg_compress
.next_scanline
< engine
->jpeg_compress
.image_height
)
639 if(interlaced_row
> last_row
) interlaced_row
= last_row
;
640 jpeg_write_scanlines(&engine
->jpeg_compress
,
641 (JSAMPROW
*)interlaced_row
,
647 jpeg_finish_compress(&engine
->jpeg_compress
);
651 /* Fix markers and write whole thing */
652 quicktime_fixmarker_jpeg(&(engine
->mjpeg_hdr
),
653 engine
->output_buffer
,
657 *image_size
= engine
->output_size
;
658 return engine
->output_buffer
;
661 /* Main loop for JPEG compression */
662 void quicktime_compressor_jpeg(mjpa_compress_engine
*engine
)
666 /* Run continuously */
669 pthread_mutex_lock(&(engine
->input_lock
));
673 /* Image compression core */
674 quicktime_compress_jpeg(engine
, engine
->row_pointers
, &fake_size
, engine
->write_next_offset
);
675 pthread_mutex_unlock(&(engine
->output_lock
));
680 void quicktime_startcompressor_jpeg(mjpa_compress_engine
*engine
)
683 struct sched_param param
;
684 pthread_mutexattr_t mutex_attr
;
686 pthread_mutexattr_init(&mutex_attr
);
687 pthread_mutex_init(&(engine
->input_lock
), &mutex_attr
);
688 pthread_mutex_lock(&(engine
->input_lock
));
689 pthread_mutex_init(&(engine
->output_lock
), &mutex_attr
);
690 pthread_mutex_lock(&(engine
->output_lock
));
692 pthread_attr_init(&attr
);
693 pthread_create(&(engine
->tid
), &attr
, (void*)quicktime_compressor_jpeg
, engine
);
696 void quicktime_compressfield_jpeg(mjpa_compress_engine
*engine
,
697 unsigned char **row_pointers
, int write_next_offset
)
699 engine
->row_pointers
= row_pointers
;
700 engine
->write_next_offset
= write_next_offset
;
701 pthread_mutex_unlock(&(engine
->input_lock
));
704 void quicktime_compresswait_jpeg(mjpa_compress_engine
*engine
)
706 pthread_mutex_lock(&(engine
->output_lock
));
709 mjpa_compress_engine
* quicktime_jpeg_new_compress_engine(int width
,
717 mjpa_compress_engine
*new_compressor
;
719 new_compressor
= malloc(sizeof(mjpa_compress_engine
));
720 new_compressor
->output_buffer
= malloc(512);
721 new_compressor
->output_allocated
= 512;
722 new_compressor
->output_size
= 0;
723 new_compressor
->row_pointers
= 0;
724 new_compressor
->write_next_offset
= 0;
725 new_compressor
->done
= 0;
726 /* Initialize the jpeglib structures here */
727 new_compressor
->jpeg_compress
.err
= jpeg_std_error(&(new_compressor
->jpeg_error
));
728 jpeg_create_compress(&(new_compressor
->jpeg_compress
));
729 new_compressor
->jpeg_compress
.input_components
= 3;
730 new_compressor
->jpeg_compress
.in_color_space
= JCS_RGB
;
731 jpeg_set_defaults(&(new_compressor
->jpeg_compress
));
732 jpeg_set_quality(&(new_compressor
->jpeg_compress
), quality
, 0);
734 new_compressor
->jpeg_compress
.dct_method
= JDCT_FLOAT
;
736 /* Progression made it twice as slow. */
737 /* jpeg_simple_progression(&(codec->compressors[i]->jpeg_compress)); */
739 /* Changing the sampling to all values but default increased compression time. */
740 /* 211111 sampling is required for playback on the LML33 */
743 /* Fix sampling for interlaced */
744 new_compressor
->jpeg_compress
.comp_info
[0].h_samp_factor
= 2;
745 new_compressor
->jpeg_compress
.comp_info
[0].v_samp_factor
= 1;
746 new_compressor
->jpeg_compress
.comp_info
[1].h_samp_factor
= 1;
747 new_compressor
->jpeg_compress
.comp_info
[1].v_samp_factor
= 1;
748 new_compressor
->jpeg_compress
.comp_info
[2].h_samp_factor
= 1;
749 new_compressor
->jpeg_compress
.comp_info
[2].v_samp_factor
= 1;
751 /* Huffman optimization saved %5 */
752 /* codec->compressors[i]->jpeg_compress.optimize_coding = TRUE; */
753 /* Omitting tables saved the same %5 */
754 /* jpeg_suppress_tables(&(codec->compressors[i]->jpeg_compress), TRUE); */
756 new_compressor
->jpeg_compress
.image_width
= width
;
757 new_compressor
->jpeg_compress
.image_height
= !interlaced
? height
: (height
>> 1);
758 new_compressor
->is_mjpa
= is_mjpa
;
759 new_compressor
->mjpeg_hdr
.mjpg_kludge
= 0;
760 new_compressor
->width
= width
;
761 new_compressor
->height
= height
;
762 new_compressor
->interlaced
= interlaced
;
763 return new_compressor
;
766 static int quicktime_encode_jpeg(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
768 long offset
= quicktime_position(file
);
771 quicktime_trak_t
*trak
= file
->vtracks
[track
].track
;
772 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
773 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
774 int is_mjpa
= codec
->jpeg_type
== 1;
775 int is_mjpb
= codec
->jpeg_type
== 2;
776 int interlaced
= is_mjpa
|| is_mjpb
;
779 unsigned char **interlaced_row
, **last_row
;
781 int height
= (int)trak
->tkhd
.track_height
;
782 int width
= (int)trak
->tkhd
.track_width
;
784 /* Create compression engines as needed */
785 for(i
= 0; i
< (interlaced
? TOTAL_MJPA_COMPRESSORS
: 1); i
++)
787 if(!codec
->compressors
[i
])
789 codec
->compressors
[i
] = quicktime_jpeg_new_compress_engine(width
,
797 /* Start threads waiting */
798 quicktime_startcompressor_jpeg(codec
->compressors
[i
]);
800 codec
->total_compressors
++;
805 /* Start the compressors on the image fields */
806 for(row_offset
= 0; row_offset
< (interlaced
? TOTAL_MJPA_COMPRESSORS
: 1) && !result
; row_offset
++)
808 quicktime_compressfield_jpeg(codec
->compressors
[row_offset
],
809 row_pointers
+ row_offset
, !row_offset
);
811 if(file
->cpus
< 2 && row_offset
< TOTAL_MJPA_COMPRESSORS
- 1)
813 quicktime_compresswait_jpeg(codec
->compressors
[row_offset
]);
817 /* Wait for the compressors and write to disk */
818 for(row_offset
= 0; row_offset
< (interlaced
? TOTAL_MJPA_COMPRESSORS
: 1) && !result
; row_offset
++)
820 if(file
->cpus
> 1 || row_offset
== TOTAL_MJPA_COMPRESSORS
- 1)
822 quicktime_compresswait_jpeg(codec
->compressors
[row_offset
]);
825 result
= quicktime_write_data(file
,
826 codec
->compressors
[row_offset
]->output_buffer
,
827 codec
->compressors
[row_offset
]->output_size
);
831 bytes
= quicktime_position(file
) - offset
;
832 quicktime_update_tables(file
,
835 vtrack
->current_chunk
,
836 vtrack
->current_position
,
840 vtrack
->current_chunk
++;