5 /* Attempt to use JPEG code from XAnim. */
6 /* Ended up 10% slower than libjpeg. */
9 struct jpeg_error_mgr pub
; /* "public" fields */
11 jmp_buf setjmp_buffer
; /* for return to caller */
14 typedef struct my_error_mgr
* my_error_ptr
;
17 my_error_exit (j_common_ptr cinfo
)
19 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
20 my_error_ptr myerr
= (my_error_ptr
) cinfo
->err
;
22 /* Always display the message. */
23 /* We could postpone this until after returning, if we chose. */
24 (*cinfo
->err
->output_message
) (cinfo
);
26 /* Return control to the setjmp point */
27 longjmp(myerr
->setjmp_buffer
, 1);
30 int quicktime_init_codec_jpeg(quicktime_video_map_t
*vtrack
)
32 vtrack
->codecs
.jpeg_codec
.quality
= 100;
33 vtrack
->codecs
.jpeg_codec
.use_float
= 0;
34 vtrack
->codecs
.jpeg_codec
.chunk_buffer
= 0;
35 vtrack
->codecs
.jpeg_codec
.chunk_buffer_len
= 0;
36 quicktime_fastjpg_init(&(vtrack
->codecs
.jpeg_codec
.fastjpg
));
39 int quicktime_delete_codec_jpeg(quicktime_video_map_t
*vtrack
)
41 if(vtrack
->codecs
.jpeg_codec
.chunk_buffer
)
43 free(vtrack
->codecs
.jpeg_codec
.chunk_buffer
);
45 quicktime_fastjpg_delete(&(vtrack
->codecs
.jpeg_codec
.fastjpg
));
48 int quicktime_set_jpeg(quicktime_t
*file
, int quality
, int use_float
)
53 for(i
= 0; i
< file
->total_vtracks
; i
++)
55 if(quicktime_match_32(quicktime_video_compressor(file
, i
), QUICKTIME_JPEG
))
57 quicktime_jpeg_codec_t
*codec
= &(file
->vtracks
[i
].codecs
.jpeg_codec
);
58 codec
->quality
= quality
;
59 codec
->use_float
= use_float
;
64 int quicktime_decode_jpeg(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
68 quicktime_trak_t
*trak
= file
->vtracks
[track
].track
;
71 if(file
->vtracks
[track
].frames_cached
)
73 chunk
= file
->vtracks
[track
].frame_cache
[file
->vtracks
[track
].current_position
];
74 chunk_size
= quicktime_frame_size(file
, file
->vtracks
[track
].current_position
, track
);
78 chunk_size
= quicktime_frame_size(file
, file
->vtracks
[track
].current_position
, track
);
79 if(file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer
)
81 if(file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer_len
< chunk_size
)
83 free(file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer
);
84 file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer
= 0;
87 if(!file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer
)
89 file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer
= malloc(chunk_size
);
90 file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer_len
= chunk_size
;
92 chunk
= file
->vtracks
[track
].codecs
.jpeg_codec
.chunk_buffer
;
93 quicktime_set_video_position(file
, file
->vtracks
[track
].current_position
, track
);
94 result
= quicktime_read_data(file
, chunk
, chunk_size
);
95 if(result
) result
= 0; else result
= 1;
98 result
= quicktime_fastjpg_decode(chunk
,
101 &(file
->vtracks
[track
].codecs
.jpeg_codec
.fastjpg
),
102 (int)trak
->tkhd
.track_width
,
103 (int)trak
->tkhd
.track_height
,
109 int quicktime_encode_jpeg(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
111 long offset
= quicktime_position(file
);
114 quicktime_trak_t
*trak
= file
->vtracks
[track
].track
;
115 int height
= trak
->tkhd
.track_height
;
116 int width
= trak
->tkhd
.track_width
;
117 struct jpeg_compress_struct jpeg_compress
;
118 struct jpeg_error_mgr jpeg_error
;
119 JSAMPROW row_pointer
[1];
122 jpeg_compress
.err
= jpeg_std_error(&jpeg_error
);
123 jpeg_create_compress(&jpeg_compress
);
124 jpeg_stdio_dest(&jpeg_compress
, quicktime_get_fd(file
));
125 jpeg_compress
.image_width
= width
;
126 jpeg_compress
.image_height
= height
;
127 jpeg_compress
.input_components
= 3;
128 jpeg_compress
.in_color_space
= JCS_RGB
;
129 jpeg_set_defaults(&jpeg_compress
);
130 jpeg_set_quality(&jpeg_compress
, file
->vtracks
[track
].codecs
.jpeg_codec
.quality
, 0);
131 if(file
->vtracks
[track
].codecs
.jpeg_codec
.use_float
)
132 jpeg_compress
.dct_method
= JDCT_FLOAT
;
134 jpeg_start_compress(&jpeg_compress
, TRUE
);
135 while(jpeg_compress
.next_scanline
< jpeg_compress
.image_height
)
137 row_pointer
[0] = row_pointers
[jpeg_compress
.next_scanline
];
138 jpeg_write_scanlines(&jpeg_compress
, row_pointer
, 1);
140 jpeg_finish_compress(&jpeg_compress
);
141 jpeg_destroy((j_common_ptr
)&jpeg_compress
);
143 bytes
= quicktime_position(file
) - offset
;
144 quicktime_update_tables(file
,
145 file
->vtracks
[track
].track
,
147 file
->vtracks
[track
].current_chunk
,
148 file
->vtracks
[track
].current_position
,
152 file
->vtracks
[track
].current_chunk
++;