2 * lossless JPEG encoder
3 * Copyright (c) 2000, 2001 Fabrice Bellard
4 * Copyright (c) 2003 Alex Beregszaszi
5 * Copyright (c) 2003-2004 Michael Niedermayer
7 * Support for external huffman table, various fixes (AVID workaround),
8 * aspecting, new decode_frame mechanism and apple mjpeg-b support
11 * This file is part of FFmpeg.
13 * FFmpeg 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.
18 * FFmpeg 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.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with FFmpeg; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 * lossless JPEG encoder.
33 #include "libavutil/frame.h"
34 #include "libavutil/mem.h"
35 #include "libavutil/opt.h"
38 #include "codec_internal.h"
40 #include "jpegtables.h"
41 #include "mjpegenc_common.h"
44 typedef struct LJpegEncContext
{
50 uint16_t huff_code_dc_luminance
[12];
51 uint16_t huff_code_dc_chrominance
[12];
52 uint8_t huff_size_dc_luminance
[12];
53 uint8_t huff_size_dc_chrominance
[12];
55 uint16_t (*scratch
)[4];
59 static int ljpeg_encode_bgr(AVCodecContext
*avctx
, PutBitContext
*pb
,
62 LJpegEncContext
*s
= avctx
->priv_data
;
63 const int width
= frame
->width
;
64 const int height
= frame
->height
;
65 const int linesize
= frame
->linesize
[0];
66 uint16_t (*buffer
)[4] = s
->scratch
;
67 int left
[4], top
[4], topleft
[4];
70 for (i
= 0; i
< 4; i
++)
71 buffer
[0][i
] = 1 << (9 - 1);
73 for (y
= 0; y
< height
; y
++) {
74 const int modified_predictor
= y
? s
->pred
: 1;
75 const uint8_t *ptr
= frame
->data
[0] + (linesize
* y
);
77 if (put_bytes_left(pb
, 0) < width
* 4 * 4) {
78 av_log(avctx
, AV_LOG_ERROR
, "encoded frame too large\n");
82 for (i
= 0; i
< 4; i
++)
83 top
[i
]= left
[i
]= topleft
[i
]= buffer
[0][i
];
85 for (x
= 0; x
< width
; x
++) {
86 if(avctx
->pix_fmt
== AV_PIX_FMT_BGR24
){
87 buffer
[x
][1] = ptr
[3 * x
+ 0] - ptr
[3 * x
+ 1] + 0x100;
88 buffer
[x
][2] = ptr
[3 * x
+ 2] - ptr
[3 * x
+ 1] + 0x100;
89 buffer
[x
][0] = (ptr
[3 * x
+ 0] + 2 * ptr
[3 * x
+ 1] + ptr
[3 * x
+ 2]) >> 2;
91 buffer
[x
][1] = ptr
[4 * x
+ 0] - ptr
[4 * x
+ 1] + 0x100;
92 buffer
[x
][2] = ptr
[4 * x
+ 2] - ptr
[4 * x
+ 1] + 0x100;
93 buffer
[x
][0] = (ptr
[4 * x
+ 0] + 2 * ptr
[4 * x
+ 1] + ptr
[4 * x
+ 2]) >> 2;
94 if (avctx
->pix_fmt
== AV_PIX_FMT_BGRA
)
95 buffer
[x
][3] = ptr
[4 * x
+ 3];
98 for (i
= 0; i
< 3 + (avctx
->pix_fmt
== AV_PIX_FMT_BGRA
); i
++) {
101 PREDICT(pred
, topleft
[i
], top
[i
], left
[i
], modified_predictor
);
104 top
[i
] = buffer
[x
+1][i
];
106 left
[i
] = buffer
[x
][i
];
108 diff
= ((left
[i
] - pred
+ 0x100) & 0x1FF) - 0x100;
110 if (i
== 0 || i
== 3)
111 ff_mjpeg_encode_dc(pb
, diff
, s
->huff_size_dc_luminance
, s
->huff_code_dc_luminance
); //FIXME ugly
113 ff_mjpeg_encode_dc(pb
, diff
, s
->huff_size_dc_chrominance
, s
->huff_code_dc_chrominance
);
121 static inline void ljpeg_encode_yuv_mb(LJpegEncContext
*s
, PutBitContext
*pb
,
122 const AVFrame
*frame
, int predictor
,
127 if (mb_x
== 0 || mb_y
== 0) {
128 for (i
= 0; i
< 3; i
++) {
130 int x
, y
, h
, v
, linesize
;
133 linesize
= frame
->linesize
[i
];
135 for (y
= 0; y
< v
; y
++) {
136 for (x
= 0; x
< h
; x
++) {
139 ptr
= frame
->data
[i
] + (linesize
* (v
* mb_y
+ y
)) + (h
* mb_x
+ x
); //FIXME optimize this crap
140 if (y
== 0 && mb_y
== 0) {
141 if (x
== 0 && mb_x
== 0)
146 if (x
== 0 && mb_x
== 0) {
147 pred
= ptr
[-linesize
];
149 PREDICT(pred
, ptr
[-linesize
- 1], ptr
[-linesize
],
155 ff_mjpeg_encode_dc(pb
, *ptr
- pred
, s
->huff_size_dc_luminance
, s
->huff_code_dc_luminance
); //FIXME ugly
157 ff_mjpeg_encode_dc(pb
, *ptr
- pred
, s
->huff_size_dc_chrominance
, s
->huff_code_dc_chrominance
);
162 for (i
= 0; i
< 3; i
++) {
164 int x
, y
, h
, v
, linesize
;
167 linesize
= frame
->linesize
[i
];
169 for (y
= 0; y
< v
; y
++) {
170 for (x
= 0; x
< h
; x
++) {
173 ptr
= frame
->data
[i
] + (linesize
* (v
* mb_y
+ y
)) + (h
* mb_x
+ x
); //FIXME optimize this crap
174 PREDICT(pred
, ptr
[-linesize
- 1], ptr
[-linesize
], ptr
[-1], predictor
);
177 ff_mjpeg_encode_dc(pb
, *ptr
- pred
, s
->huff_size_dc_luminance
, s
->huff_code_dc_luminance
); //FIXME ugly
179 ff_mjpeg_encode_dc(pb
, *ptr
- pred
, s
->huff_size_dc_chrominance
, s
->huff_code_dc_chrominance
);
186 static int ljpeg_encode_yuv(AVCodecContext
*avctx
, PutBitContext
*pb
,
187 const AVFrame
*frame
)
189 LJpegEncContext
*s
= avctx
->priv_data
;
190 const int mb_width
= (avctx
->width
+ s
->hsample
[0] - 1) / s
->hsample
[0];
191 const int mb_height
= (avctx
->height
+ s
->vsample
[0] - 1) / s
->vsample
[0];
194 for (mb_y
= 0; mb_y
< mb_height
; mb_y
++) {
195 if (put_bytes_left(pb
, 0) <
196 mb_width
* 4 * 3 * s
->hsample
[0] * s
->vsample
[0]) {
197 av_log(avctx
, AV_LOG_ERROR
, "encoded frame too large\n");
201 for (mb_x
= 0; mb_x
< mb_width
; mb_x
++)
202 ljpeg_encode_yuv_mb(s
, pb
, frame
, s
->pred
, mb_x
, mb_y
);
208 static int ljpeg_encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
209 const AVFrame
*pict
, int *got_packet
)
211 LJpegEncContext
*s
= avctx
->priv_data
;
213 const int width
= avctx
->width
;
214 const int height
= avctx
->height
;
215 const int mb_width
= (width
+ s
->hsample
[0] - 1) / s
->hsample
[0];
216 const int mb_height
= (height
+ s
->vsample
[0] - 1) / s
->vsample
[0];
217 size_t max_pkt_size
= FF_INPUT_BUFFER_MIN_SIZE
;
218 int ret
, header_bits
;
220 if( avctx
->pix_fmt
== AV_PIX_FMT_BGR0
221 || avctx
->pix_fmt
== AV_PIX_FMT_BGR24
)
222 max_pkt_size
+= width
* height
* 3 * 4;
223 else if(avctx
->pix_fmt
== AV_PIX_FMT_BGRA
)
224 max_pkt_size
+= width
* height
* 4 * 4;
226 max_pkt_size
+= mb_width
* mb_height
* 3 * 4
227 * s
->hsample
[0] * s
->vsample
[0];
230 if ((ret
= ff_mjpeg_add_icc_profile_size(avctx
, pict
, &max_pkt_size
)) < 0)
232 if ((ret
= ff_alloc_packet(avctx
, pkt
, max_pkt_size
)) < 0)
235 init_put_bits(&pb
, pkt
->data
, pkt
->size
);
237 ff_mjpeg_encode_picture_header(avctx
, &pb
, pict
, NULL
, NULL
,
238 s
->pred
, NULL
, NULL
, 0);
240 header_bits
= put_bits_count(&pb
);
242 if( avctx
->pix_fmt
== AV_PIX_FMT_BGR0
243 || avctx
->pix_fmt
== AV_PIX_FMT_BGRA
244 || avctx
->pix_fmt
== AV_PIX_FMT_BGR24
)
245 ret
= ljpeg_encode_bgr(avctx
, &pb
, pict
);
247 ret
= ljpeg_encode_yuv(avctx
, &pb
, pict
);
251 ff_mjpeg_escape_FF(&pb
, header_bits
>> 3);
252 ff_mjpeg_encode_picture_trailer(&pb
, header_bits
);
255 pkt
->size
= put_bits_ptr(&pb
) - pb
.buf
;
261 static av_cold
int ljpeg_encode_close(AVCodecContext
*avctx
)
263 LJpegEncContext
*s
= avctx
->priv_data
;
265 av_freep(&s
->scratch
);
270 static av_cold
int ljpeg_encode_init(AVCodecContext
*avctx
)
272 int ret
= ff_mjpeg_encode_check_pix_fmt(avctx
);
273 LJpegEncContext
*s
= avctx
->priv_data
;
278 s
->scratch
= av_malloc_array(avctx
->width
+ 1, sizeof(*s
->scratch
));
280 return AVERROR(ENOMEM
);
282 ff_mjpeg_init_hvsample(avctx
, s
->hsample
, s
->vsample
);
284 ff_mjpeg_build_huffman_codes(s
->huff_size_dc_luminance
,
285 s
->huff_code_dc_luminance
,
286 ff_mjpeg_bits_dc_luminance
,
288 ff_mjpeg_build_huffman_codes(s
->huff_size_dc_chrominance
,
289 s
->huff_code_dc_chrominance
,
290 ff_mjpeg_bits_dc_chrominance
,
296 #define OFFSET(x) offsetof(LJpegEncContext, x)
297 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
298 static const AVOption options
[] = {
299 { "pred", "Prediction method", OFFSET(pred
), AV_OPT_TYPE_INT
, { .i64
= 1 }, 1, 3, VE
, .unit
= "pred" },
300 { "left", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 1 }, INT_MIN
, INT_MAX
, VE
, .unit
= "pred" },
301 { "plane", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 2 }, INT_MIN
, INT_MAX
, VE
, .unit
= "pred" },
302 { "median", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 3 }, INT_MIN
, INT_MAX
, VE
, .unit
= "pred" },
307 static const AVClass ljpeg_class
= {
308 .class_name
= "ljpeg",
309 .item_name
= av_default_item_name
,
311 .version
= LIBAVUTIL_VERSION_INT
,
314 const FFCodec ff_ljpeg_encoder
= {
316 CODEC_LONG_NAME("Lossless JPEG"),
317 .p
.type
= AVMEDIA_TYPE_VIDEO
,
318 .p
.id
= AV_CODEC_ID_LJPEG
,
319 .p
.capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_FRAME_THREADS
|
320 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
,
321 .priv_data_size
= sizeof(LJpegEncContext
),
322 .p
.priv_class
= &ljpeg_class
,
323 .init
= ljpeg_encode_init
,
324 FF_CODEC_ENCODE_CB(ljpeg_encode_frame
),
325 .close
= ljpeg_encode_close
,
326 .p
.pix_fmts
= (const enum AVPixelFormat
[]){
327 AV_PIX_FMT_BGR24
, AV_PIX_FMT_BGRA
, AV_PIX_FMT_BGR0
,
328 AV_PIX_FMT_YUVJ420P
, AV_PIX_FMT_YUVJ444P
, AV_PIX_FMT_YUVJ422P
,
329 AV_PIX_FMT_YUV420P
, AV_PIX_FMT_YUV444P
, AV_PIX_FMT_YUV422P
,
331 .color_ranges
= AVCOL_RANGE_MPEG
| AVCOL_RANGE_JPEG
,