ljpegenc: split bgr encoding into a separate function
[libav.git] / libavcodec / ljpegenc.c
CommitLineData
d9c9259f
AJ
1/*
2 * lossless JPEG encoder
406792e7 3 * Copyright (c) 2000, 2001 Fabrice Bellard
d9c9259f
AJ
4 * Copyright (c) 2003 Alex Beregszaszi
5 * Copyright (c) 2003-2004 Michael Niedermayer
6 *
7b94177e
DB
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 *
2912e87a 11 * This file is part of Libav.
d9c9259f 12 *
2912e87a 13 * Libav is free software; you can redistribute it and/or
d9c9259f
AJ
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 *
2912e87a 18 * Libav is distributed in the hope that it will be useful,
d9c9259f
AJ
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
2912e87a 24 * License along with Libav; if not, write to the Free Software
d9c9259f 25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d9c9259f
AJ
26 */
27
28/**
ba87f080 29 * @file
d9c9259f
AJ
30 * lossless JPEG encoder.
31 */
32
24abd806
AK
33#include "libavutil/frame.h"
34#include "libavutil/mem.h"
35#include "libavutil/pixdesc.h"
36
d9c9259f 37#include "avcodec.h"
24abd806 38#include "dsputil.h"
8e8124e1 39#include "internal.h"
d9c9259f
AJ
40#include "mpegvideo.h"
41#include "mjpeg.h"
42#include "mjpegenc.h"
43
24abd806
AK
44typedef 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;
d9c9259f 59
fa447681
AK
60static 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
0cdbc4d3
AK
115static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
116 const AVFrame *pict, int *got_packet)
8e8124e1 117{
24abd806
AK
118 LJpegEncContext *s = avctx->priv_data;
119 PutBitContext pb;
120 const int width = avctx->width;
121 const int height = avctx->height;
d9c9259f 122 const int predictor= avctx->prediction_method+1;
24abd806
AK
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;
8e8124e1 127
daffed3b
AK
128 if (avctx->pix_fmt == AV_PIX_FMT_BGR24)
129 max_pkt_size += width * height * 3 * 3;
8e8124e1
AK
130 else {
131 max_pkt_size += mb_width * mb_height * 3 * 4
24abd806 132 * s->hsample[0] * s->vsample[0];
8e8124e1
AK
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 }
d9c9259f 138
24abd806 139 init_put_bits(&pb, pkt->data, pkt->size);
d9c9259f 140
24abd806
AK
141 ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable,
142 s->matrix);
d9c9259f 143
24abd806 144 header_bits = put_bits_count(&pb);
d9c9259f 145
daffed3b 146 if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
fa447681
AK
147 ret = ljpeg_encode_bgr(avctx, &pb, pict);
148 if (ret < 0)
149 return ret;
d9c9259f
AJ
150 }else{
151 int mb_x, mb_y, i;
d9c9259f
AJ
152
153 for(mb_y = 0; mb_y < mb_height; mb_y++) {
24abd806
AK
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");
d9c9259f
AJ
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;
24abd806
AK
164 h = s->hsample[i];
165 v = s->vsample[i];
166 linesize = pict->linesize[i];
d9c9259f
AJ
167
168 for(y=0; y<v; y++){
169 for(x=0; x<h; x++){
170 int pred;
171
24abd806 172 ptr = pict->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
d9c9259f
AJ
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)
24abd806 188 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
d9c9259f 189 else
24abd806 190 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
d9c9259f
AJ
191 }
192 }
193 }
194 }else{
195 for(i=0;i<3;i++) {
196 uint8_t *ptr;
197 int x, y, h, v, linesize;
24abd806
AK
198 h = s->hsample[i];
199 v = s->vsample[i];
86eb2eaa 200 linesize = pict->linesize[i];
d9c9259f
AJ
201
202 for(y=0; y<v; y++){
203 for(x=0; x<h; x++){
204 int pred;
205
86eb2eaa 206 ptr = pict->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
d9c9259f
AJ
207 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
208
209 if(i==0)
24abd806 210 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
d9c9259f 211 else
24abd806 212 ff_mjpeg_encode_dc(&pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
d9c9259f
AJ
213 }
214 }
215 }
216 }
217 }
218 }
219 }
220
221 emms_c();
222
24abd806 223 ff_mjpeg_encode_picture_trailer(&pb, header_bits);
d9c9259f 224
24abd806
AK
225 flush_put_bits(&pb);
226 pkt->size = put_bits_ptr(&pb) - pb.buf;
8e8124e1
AK
227 pkt->flags |= AV_PKT_FLAG_KEY;
228 *got_packet = 1;
229
230 return 0;
d9c9259f
AJ
231}
232
24abd806
AK
233static 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
243static 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
daffed3b 273 if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
24abd806
AK
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}
d9c9259f 297
24abd806 298AVCodec ff_ljpeg_encoder = {
86714887 299 .name = "ljpeg",
b2bed932 300 .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
86714887 301 .type = AVMEDIA_TYPE_VIDEO,
36ef5369 302 .id = AV_CODEC_ID_LJPEG,
24abd806
AK
303 .priv_data_size = sizeof(LJpegEncContext),
304 .init = ljpeg_encode_init,
0cdbc4d3 305 .encode2 = ljpeg_encode_frame,
24abd806
AK
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,
daffed3b 310 AV_PIX_FMT_BGR24,
24abd806
AK
311 AV_PIX_FMT_YUV420P,
312 AV_PIX_FMT_YUV422P,
313 AV_PIX_FMT_YUVJ444P,
314 AV_PIX_FMT_NONE },
d9c9259f 315};