4 #include "colormodels.h"
5 #include "funcprotos.h"
11 #define JPEG_PROGRESSIVE 0
17 unsigned char *buffer
;
18 long buffer_allocated
;
22 unsigned char *temp_video
;
26 } quicktime_jpeg_codec_t
;
28 static int delete_codec(quicktime_video_map_t
*vtrack
)
30 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
33 if(codec
->mjpeg
) mjpeg_delete(codec
->mjpeg
);
37 free(codec
->temp_video
);
42 void quicktime_set_jpeg(quicktime_t
*file
, int quality
, int use_float
)
48 for(i
= 0; i
< file
->total_vtracks
; i
++)
50 if(quicktime_match_32(quicktime_video_compressor(file
, i
), QUICKTIME_JPEG
) ||
51 quicktime_match_32(quicktime_video_compressor(file
, i
), QUICKTIME_MJPA
) ||
52 quicktime_match_32(quicktime_video_compressor(file
, i
), QUICKTIME_RTJ0
))
54 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)file
->vtracks
[i
].codec
)->priv
;
55 codec
->quality
= quality
;
56 codec
->use_float
= use_float
;
63 static void initialize(quicktime_video_map_t
*vtrack
)
65 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
66 if(!codec
->initialized
)
68 /* Init private items */
69 codec
->mjpeg
= mjpeg_new(vtrack
->track
->tkhd
.track_width
,
70 vtrack
->track
->tkhd
.track_height
,
71 1 + (codec
->jpeg_type
== JPEG_MJPA
|| codec
->jpeg_type
== JPEG_MJPB
));
73 /* This information must be stored in the initialization routine because of */
74 /* direct copy rendering. Quicktime for Windows must have this information. */
75 if(codec
->jpeg_type
== JPEG_MJPA
&&
76 !vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].fields
)
78 vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].fields
= 2;
79 vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].field_dominance
= 1;
81 codec
->initialized
= 1;
85 static int decode(quicktime_t
*file
,
86 unsigned char **row_pointers
,
89 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
91 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
92 quicktime_trak_t
*trak
= vtrack
->track
;
93 mjpeg_t
*mjpeg
= codec
->mjpeg
;
94 long size
, field2_offset
= 0;
95 int track_height
= trak
->tkhd
.track_height
;
96 int track_width
= trak
->tkhd
.track_width
;
98 int field_dominance
= trak
->mdia
.minf
.stbl
.stsd
.table
[0].field_dominance
;
100 mjpeg_set_cpus(codec
->mjpeg
, file
->cpus
);
102 mjpeg_set_rowspan(codec
->mjpeg
, file
->row_span
);
104 mjpeg_set_rowspan(codec
->mjpeg
, 0);
106 quicktime_set_video_position(file
, vtrack
->current_position
, track
);
107 size
= quicktime_frame_size(file
, vtrack
->current_position
, track
);
108 codec
->buffer_size
= size
;
110 if(size
> codec
->buffer_allocated
)
112 codec
->buffer_allocated
= size
;
113 codec
->buffer
= realloc(codec
->buffer
, codec
->buffer_allocated
);
116 result
= !quicktime_read_data(file
, codec
->buffer
, size
);
118 * printf("decode 1 %02x %02x %02x %02x %02x %02x %02x %02x\n",
132 if(mjpeg_get_fields(mjpeg
) == 2)
136 field2_offset
= mjpeg_get_avi_field2(codec
->buffer
,
142 field2_offset
= mjpeg_get_quicktime_field2(codec
->buffer
,
147 printf("decode: FYI field2_offset=0\n");
148 field2_offset
= mjpeg_get_field2(codec
->buffer
, size
);
156 //printf("decode 2 %d\n", field2_offset);
158 * printf("decode result=%d field1=%llx field2=%llx size=%d %02x %02x %02x %02x\n",
160 * quicktime_position(file) - size,
161 * quicktime_position(file) - size + field2_offset,
165 * codec->buffer[field2_offset + 0],
166 * codec->buffer[field2_offset + 1]);
169 if(file
->in_x
== 0 &&
171 file
->in_w
== track_width
&&
172 file
->in_h
== track_height
&&
173 file
->out_w
== track_width
&&
174 file
->out_h
== track_height
)
177 mjpeg_decompress(codec
->mjpeg
,
191 unsigned char **temp_rows
;
192 int temp_cmodel
= BC_YUV888
;
193 int temp_rowsize
= cmodel_calculate_pixelsize(temp_cmodel
) * track_width
;
195 if(!codec
->temp_video
)
196 codec
->temp_video
= malloc(temp_rowsize
* track_height
);
197 temp_rows
= malloc(sizeof(unsigned char*) * track_height
);
198 for(i
= 0; i
< track_height
; i
++)
199 temp_rows
[i
] = codec
->temp_video
+ i
* temp_rowsize
;
201 //printf("decode 10\n");
202 mjpeg_decompress(codec
->mjpeg
,
213 cmodel_transfer(row_pointers
,
235 //printf("decode 30\n");
238 //printf("decode 40\n");
241 //printf("decode 2 %d\n", result);
246 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
248 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
250 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
251 quicktime_trak_t
*trak
= vtrack
->track
;
252 mjpeg_set_quality(codec
->mjpeg
, codec
->quality
);
253 mjpeg_set_float(codec
->mjpeg
, codec
->use_float
);
254 int64_t offset
= quicktime_position(file
);
257 quicktime_atom_t chunk_atom
;
259 //printf("encode 1\n");
260 mjpeg_set_cpus(codec
->mjpeg
, file
->cpus
);
262 mjpeg_compress(codec
->mjpeg
,
269 if(codec
->jpeg_type
== JPEG_MJPA
)
273 mjpeg_insert_avi_markers(&codec
->mjpeg
->output_data
,
274 &codec
->mjpeg
->output_size
,
275 &codec
->mjpeg
->output_allocated
,
281 mjpeg_insert_quicktime_markers(&codec
->mjpeg
->output_data
,
282 &codec
->mjpeg
->output_size
,
283 &codec
->mjpeg
->output_allocated
,
289 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
290 result
= !quicktime_write_data(file
,
291 mjpeg_output_buffer(codec
->mjpeg
),
292 mjpeg_output_size(codec
->mjpeg
));
293 quicktime_write_chunk_footer(file
,
295 vtrack
->current_chunk
,
299 vtrack
->current_chunk
++;
300 //printf("encode 100\n");
304 static int reads_colormodel(quicktime_t
*file
,
308 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
309 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
311 // Some JPEG_PROGRESSIVE is BC_YUV422P
312 if(codec
->jpeg_type
== JPEG_PROGRESSIVE
)
314 return (colormodel
== BC_RGB888
||
315 colormodel
== BC_YUV888
||
316 colormodel
== BC_YUV420P
||
317 colormodel
== BC_YUV422P
||
318 colormodel
== BC_YUV422
);
322 return (colormodel
== BC_RGB888
||
323 colormodel
== BC_YUV888
||
324 // colormodel == BC_YUV420P ||
325 colormodel
== BC_YUV422P
||
326 colormodel
== BC_YUV422
);
327 // The BC_YUV420P option was provided only for mpeg2movie use.because some
328 // interlaced movies were accidentally in YUV4:2:0
332 static int writes_colormodel(quicktime_t
*file
,
336 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
337 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
339 if(codec
->jpeg_type
== JPEG_PROGRESSIVE
)
341 return (colormodel
== BC_RGB888
||
342 colormodel
== BC_YUV888
||
343 colormodel
== BC_YUV420P
);
347 return (colormodel
== BC_RGB888
||
348 colormodel
== BC_YUV888
||
349 colormodel
== BC_YUV422P
);
353 static int set_parameter(quicktime_t
*file
,
358 quicktime_jpeg_codec_t
*codec
= ((quicktime_codec_t
*)file
->vtracks
[track
].codec
)->priv
;
360 if(!strcasecmp(key
, "jpeg_quality"))
362 codec
->quality
= *(int*)value
;
365 if(!strcasecmp(key
, "jpeg_usefloat"))
367 codec
->use_float
= *(int*)value
;
372 static void init_codec_common(quicktime_video_map_t
*vtrack
, char *compressor
)
374 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
375 quicktime_jpeg_codec_t
*codec
;
378 codec
= codec_base
->priv
= calloc(1, sizeof(quicktime_jpeg_codec_t
));
379 if(quicktime_match_32(compressor
, QUICKTIME_JPEG
))
380 codec
->jpeg_type
= JPEG_PROGRESSIVE
;
381 if(quicktime_match_32(compressor
, QUICKTIME_MJPA
))
382 codec
->jpeg_type
= JPEG_MJPA
;
384 codec
->use_float
= 0;
386 /* Init public items */
387 codec_base
->delete_vcodec
= delete_codec
;
388 codec_base
->decode_video
= decode
;
389 codec_base
->encode_video
= encode
;
390 codec_base
->decode_audio
= 0;
391 codec_base
->encode_audio
= 0;
392 codec_base
->reads_colormodel
= reads_colormodel
;
393 codec_base
->writes_colormodel
= writes_colormodel
;
394 codec_base
->set_parameter
= set_parameter
;
395 codec_base
->fourcc
= compressor
;
396 codec_base
->title
= (codec
->jpeg_type
== JPEG_PROGRESSIVE
? "JPEG Photo" : "Motion JPEG A");
397 codec_base
->desc
= codec_base
->title
;
401 void quicktime_init_codec_jpeg(quicktime_video_map_t
*vtrack
)
403 init_codec_common(vtrack
, QUICKTIME_JPEG
);
406 void quicktime_init_codec_mjpa(quicktime_video_map_t
*vtrack
)
408 init_codec_common(vtrack
, QUICKTIME_MJPA
);
411 void quicktime_init_codec_mjpg(quicktime_video_map_t
*vtrack
)
413 init_codec_common(vtrack
, "MJPG");