ljpegenc: split bgr encoding into a separate function
[libav.git] / libavcodec / ljpegenc.c
1 /*
2 * lossless JPEG encoder
3 * Copyright (c) 2000, 2001 Fabrice Bellard
4 * Copyright (c) 2003 Alex Beregszaszi
5 * Copyright (c) 2003-2004 Michael Niedermayer
6 *
7 * Support for external huffman table, various fixes (AVID workaround),
8 * aspecting, new decode_frame mechanism and apple mjpeg-b support
9 * by Alex Beregszaszi
10 *
11 * This file is part of Libav.
12 *
13 * Libav is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * Libav is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with Libav; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28 /**
29 * @file
30 * lossless JPEG encoder.
31 */
32
33 #include "libavutil/frame.h"
34 #include "libavutil/mem.h"
35 #include "libavutil/pixdesc.h"
36
37 #include "avcodec.h"
38 #include "dsputil.h"
39 #include "internal.h"
40 #include "mpegvideo.h"
41 #include "mjpeg.h"
42 #include "mjpegenc.h"
43
44 typedef struct LJpegEncContext {
45 DSPContext dsp;
46 ScanTable scantable;
47 uint16_t matrix[64];
48
49 int vsample[3];
50 int hsample[3];
51
52 uint16_t huff_code_dc_luminance[12];
53 uint16_t huff_code_dc_chrominance[12];
54 uint8_t huff_size_dc_luminance[12];
55 uint8_t huff_size_dc_chrominance[12];
56
57 uint16_t (*scratch)[4];
58 } LJpegEncContext;
59
60 static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb,
61 const AVFrame *frame)
62 {
63 LJpegEncContext *s = avctx->priv_data;
64 const int width = frame->width;
65 const int height = frame->height;
66 const int linesize = frame->linesize[0];
67 uint16_t (*buffer)[4] = s->scratch;
68 const int predictor = avctx->prediction_method+1;
69 int left[3], top[3], topleft[3];
70 int x, y, i;
71
72 for (i = 0; i < 3; i++)
73 buffer[0][i] = 1 << (9 - 1);
74
75 for (y = 0; y < height; y++) {
76 const int modified_predictor = y ? predictor : 1;
77 uint8_t *ptr = frame->data[0] + (linesize * y);
78
79 if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < width * 3 * 3) {
80 av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
81 return -1;
82 }
83
84 for (i = 0; i < 3; i++)
85 top[i]= left[i]= topleft[i]= buffer[0][i];
86
87 for (x = 0; x < width; x++) {
88 buffer[x][1] = ptr[3 * x + 0] - ptr[3 * x + 1] + 0x100;
89 buffer[x][2] = ptr[3 * x + 2] - ptr[3 * x + 1] + 0x100;
90 buffer[x][0] = (ptr[3 * x + 0] + 2 * ptr[3 * x + 1] + ptr[3 * x + 2]) >> 2;
91
92 for (i = 0; i < 3; i++) {
93 int pred, diff;
94
95 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
96
97 topleft[i] = top[i];
98 top[i] = buffer[x+1][i];
99
100 left[i] = buffer[x][i];
101
102 diff = ((left[i] - pred + 0x100) & 0x1FF) - 0x100;
103
104 if (i == 0)
105 ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
106 else
107 ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
108 }
109 }
110 }
111
112 return 0;
113 }
114
115 static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
116 const AVFrame *pict, int *got_packet)
117 {
118 LJpegEncContext *s = avctx->priv_data;
119 PutBitContext pb;
120 const int width = avctx->width;
121 const int height = avctx->height;
122 const int predictor= avctx->prediction_method+1;
123 const int mb_width = (width + s->hsample[0] - 1) / s->hsample[0];
124 const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0];
125 int max_pkt_size = FF_MIN_BUFFER_SIZE;
126 int ret, header_bits;
127
128 if (avctx->pix_fmt == AV_PIX_FMT_BGR24)
129 max_pkt_size += width * height * 3 * 3;
130 else {
131 max_pkt_size += mb_width * mb_height * 3 * 4
132 * s->hsample[0] * s->vsample[0];
133 }
134 if ((ret = ff_alloc_packet(pkt, max_pkt_size)) < 0) {
135 av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", max_pkt_size);
136 return ret;
137 }
138
139 init_put_bits(&pb, pkt->data, pkt->size);
140
141 ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable,
142 s->matrix);
143
144 header_bits = put_bits_count(&pb);
145
146 if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
147 ret = ljpeg_encode_bgr(avctx, &pb, pict);
148 if (ret < 0)
149 return ret;
150 }else{
151 int mb_x, mb_y, i;
152
153 for(mb_y = 0; mb_y < mb_height; mb_y++) {
154 if (pb.buf_end - pb.buf - (put_bits_count(&pb) >> 3) <
155 mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) {
156 av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
157 return -1;
158 }
159 for(mb_x = 0; mb_x < mb_width; mb_x++) {
160 if(mb_x==0 || mb_y==0){
161 for(i=0;i<3;i++) {
162 uint8_t *ptr;
163 int x, y, h, v, linesize;
164 h = s->hsample[i];
165 v = s->vsample[i];
166 linesize = pict->linesize[i];
167
168 for(y=0; y<v; y++){
169 for(x=0; x<h; x++){
170 int pred;
171
172 ptr = pict->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
173 if(y==0 && mb_y==0){
174 if(x==0 && mb_x==0){
175 pred= 128;
176 }else{
177 pred= ptr[-1];
178 }
179 }else{
180 if(x==0 && mb_x==0){
181 pred= ptr[-linesize];
182 }else{
183 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
184 }
185 }
186
187 if(i==0)
188 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
189 else
190 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
191 }
192 }
193 }
194 }else{
195 for(i=0;i<3;i++) {
196 uint8_t *ptr;
197 int x, y, h, v, linesize;
198 h = s->hsample[i];
199 v = s->vsample[i];
200 linesize = pict->linesize[i];
201
202 for(y=0; y<v; y++){
203 for(x=0; x<h; x++){
204 int pred;
205
206 ptr = pict->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
207 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
208
209 if(i==0)
210 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
211 else
212 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
213 }
214 }
215 }
216 }
217 }
218 }
219 }
220
221 emms_c();
222
223 ff_mjpeg_encode_picture_trailer(&pb, header_bits);
224
225 flush_put_bits(&pb);
226 pkt->size = put_bits_ptr(&pb) - pb.buf;
227 pkt->flags |= AV_PKT_FLAG_KEY;
228 *got_packet = 1;
229
230 return 0;
231 }
232
233 static av_cold int ljpeg_encode_close(AVCodecContext *avctx)
234 {
235 LJpegEncContext *s = avctx->priv_data;
236
237 av_frame_free(&avctx->coded_frame);
238 av_freep(&s->scratch);
239
240 return 0;
241 }
242
243 static av_cold int ljpeg_encode_init(AVCodecContext *avctx)
244 {
245 LJpegEncContext *s = avctx->priv_data;
246 int chroma_v_shift, chroma_h_shift;
247
248 if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
249 avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
250 avctx->pix_fmt == AV_PIX_FMT_YUV444P) &&
251 avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
252 av_log(avctx, AV_LOG_ERROR,
253 "Limited range YUV is non-standard, set strict_std_compliance to "
254 "at least unofficial to use it.\n");
255 return AVERROR(EINVAL);
256 }
257
258 avctx->coded_frame = av_frame_alloc();
259 if (!avctx->coded_frame)
260 return AVERROR(ENOMEM);
261
262 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
263 avctx->coded_frame->key_frame = 1;
264
265 s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch));
266
267 ff_dsputil_init(&s->dsp, avctx);
268 ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
269
270 av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,
271 &chroma_v_shift);
272
273 if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
274 s->vsample[0] = s->hsample[0] =
275 s->vsample[1] = s->hsample[1] =
276 s->vsample[2] = s->hsample[2] = 1;
277 } else {
278 s->vsample[0] = 2;
279 s->vsample[1] = 2 >> chroma_v_shift;
280 s->vsample[2] = 2 >> chroma_v_shift;
281 s->hsample[0] = 2;
282 s->hsample[1] = 2 >> chroma_h_shift;
283 s->hsample[2] = 2 >> chroma_h_shift;
284 }
285
286 ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,
287 s->huff_code_dc_luminance,
288 avpriv_mjpeg_bits_dc_luminance,
289 avpriv_mjpeg_val_dc);
290 ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance,
291 s->huff_code_dc_chrominance,
292 avpriv_mjpeg_bits_dc_chrominance,
293 avpriv_mjpeg_val_dc);
294
295 return 0;
296 }
297
298 AVCodec ff_ljpeg_encoder = {
299 .name = "ljpeg",
300 .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
301 .type = AVMEDIA_TYPE_VIDEO,
302 .id = AV_CODEC_ID_LJPEG,
303 .priv_data_size = sizeof(LJpegEncContext),
304 .init = ljpeg_encode_init,
305 .encode2 = ljpeg_encode_frame,
306 .close = ljpeg_encode_close,
307 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVJ420P,
308 AV_PIX_FMT_YUVJ422P,
309 AV_PIX_FMT_YUVJ444P,
310 AV_PIX_FMT_BGR24,
311 AV_PIX_FMT_YUV420P,
312 AV_PIX_FMT_YUV422P,
313 AV_PIX_FMT_YUVJ444P,
314 AV_PIX_FMT_NONE },
315 };