GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/ljpegenc.c Lines: 92 147 62.6 %
Date: 2019-11-22 03:34:36 Branches: 51 118 43.2 %

Line Branch Exec Source
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 FFmpeg.
12
 *
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.
17
 *
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.
22
 *
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
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 "idctdsp.h"
39
#include "internal.h"
40
#include "jpegtables.h"
41
#include "mjpegenc_common.h"
42
#include "mjpeg.h"
43
44
typedef struct LJpegEncContext {
45
    AVClass *class;
46
    IDCTDSPContext idsp;
47
    ScanTable scantable;
48
    uint16_t matrix[64];
49
50
    int vsample[4];
51
    int hsample[4];
52
53
    uint16_t huff_code_dc_luminance[12];
54
    uint16_t huff_code_dc_chrominance[12];
55
    uint8_t  huff_size_dc_luminance[12];
56
    uint8_t  huff_size_dc_chrominance[12];
57
58
    uint16_t (*scratch)[4];
59
    int pred;
60
} LJpegEncContext;
61
62
static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb,
63
                            const AVFrame *frame)
64
{
65
    LJpegEncContext *s    = avctx->priv_data;
66
    const int width       = frame->width;
67
    const int height      = frame->height;
68
    const int linesize    = frame->linesize[0];
69
    uint16_t (*buffer)[4] = s->scratch;
70
    int left[4], top[4], topleft[4];
71
    int x, y, i;
72
73
#if FF_API_PRIVATE_OPT
74
FF_DISABLE_DEPRECATION_WARNINGS
75
    if (avctx->prediction_method)
76
        s->pred = avctx->prediction_method + 1;
77
FF_ENABLE_DEPRECATION_WARNINGS
78
#endif
79
80
    for (i = 0; i < 4; i++)
81
        buffer[0][i] = 1 << (9 - 1);
82
83
    for (y = 0; y < height; y++) {
84
        const int modified_predictor = y ? s->pred : 1;
85
        uint8_t *ptr = frame->data[0] + (linesize * y);
86
87
        if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < width * 4 * 4) {
88
            av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
89
            return -1;
90
        }
91
92
        for (i = 0; i < 4; i++)
93
            top[i]= left[i]= topleft[i]= buffer[0][i];
94
95
        for (x = 0; x < width; x++) {
96
            if(avctx->pix_fmt == AV_PIX_FMT_BGR24){
97
                buffer[x][1] =  ptr[3 * x + 0] -     ptr[3 * x + 1] + 0x100;
98
                buffer[x][2] =  ptr[3 * x + 2] -     ptr[3 * x + 1] + 0x100;
99
                buffer[x][0] = (ptr[3 * x + 0] + 2 * ptr[3 * x + 1] + ptr[3 * x + 2]) >> 2;
100
            }else{
101
                buffer[x][1] =  ptr[4 * x + 0] -     ptr[4 * x + 1] + 0x100;
102
                buffer[x][2] =  ptr[4 * x + 2] -     ptr[4 * x + 1] + 0x100;
103
                buffer[x][0] = (ptr[4 * x + 0] + 2 * ptr[4 * x + 1] + ptr[4 * x + 2]) >> 2;
104
                if (avctx->pix_fmt == AV_PIX_FMT_BGRA)
105
                    buffer[x][3] =  ptr[4 * x + 3];
106
            }
107
108
            for (i = 0; i < 3 + (avctx->pix_fmt == AV_PIX_FMT_BGRA); i++) {
109
                int pred, diff;
110
111
                PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
112
113
                topleft[i] = top[i];
114
                top[i]     = buffer[x+1][i];
115
116
                left[i]    = buffer[x][i];
117
118
                diff       = ((left[i] - pred + 0x100) & 0x1FF) - 0x100;
119
120
                if (i == 0 || i == 3)
121
                    ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
122
                else
123
                    ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
124
            }
125
        }
126
    }
127
128
    return 0;
129
}
130
131
3816050
static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb,
132
                                       const AVFrame *frame, int predictor,
133
                                       int mb_x, int mb_y)
134
{
135
    int i;
136
137

3816050
    if (mb_x == 0 || mb_y == 0) {
138
198000
        for (i = 0; i < 3; i++) {
139
            uint8_t *ptr;
140
            int x, y, h, v, linesize;
141
148500
            h = s->hsample[i];
142
148500
            v = s->vsample[i];
143
148500
            linesize = frame->linesize[i];
144
145
346500
            for (y = 0; y < v; y++) {
146
495000
                for (x = 0; x < h; x++) {
147
                    int pred;
148
149
297000
                    ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
150

297000
                    if (y == 0 && mb_y == 0) {
151

109000
                        if (x == 0 && mb_x == 0)
152
600
                            pred = 128;
153
                        else
154
108400
                            pred = ptr[-1];
155
                    } else {
156

188000
                        if (x == 0 && mb_x == 0) {
157
89200
                            pred = ptr[-linesize];
158
                        } else {
159


98800
                            PREDICT(pred, ptr[-linesize - 1], ptr[-linesize],
160
                                    ptr[-1], predictor);
161
                        }
162
                    }
163
164
297000
                    if (i == 0)
165
198000
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
166
                    else
167
99000
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
168
                }
169
            }
170
        }
171
    } else {
172
15066200
        for (i = 0; i < 3; i++) {
173
            uint8_t *ptr;
174
            int x, y, h, v, linesize;
175
11299650
            h = s->hsample[i];
176
11299650
            v = s->vsample[i];
177
11299650
            linesize = frame->linesize[i];
178
179
26365850
            for (y = 0; y < v; y++) {
180
37665500
                for (x = 0; x < h; x++) {
181
                    int pred;
182
183
22599300
                    ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
184


22599300
                    PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], ptr[-1], predictor);
185
186
22599300
                    if (i == 0)
187
15066200
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
188
                    else
189
7533100
                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
190
                }
191
            }
192
        }
193
    }
194
3816050
}
195
196
200
static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb,
197
                            const AVFrame *frame)
198
{
199
200
    LJpegEncContext *s  = avctx->priv_data;
200
200
    const int mb_width  = (avctx->width  + s->hsample[0] - 1) / s->hsample[0];
201
200
    const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0];
202
    int mb_x, mb_y;
203
204
#if FF_API_PRIVATE_OPT
205
FF_DISABLE_DEPRECATION_WARNINGS
206
200
    if (avctx->prediction_method)
207
        s->pred = avctx->prediction_method + 1;
208
FF_ENABLE_DEPRECATION_WARNINGS
209
#endif
210
211
22650
    for (mb_y = 0; mb_y < mb_height; mb_y++) {
212
22450
        if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) <
213
22450
            mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) {
214
            av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
215
            return -1;
216
        }
217
218
3838500
        for (mb_x = 0; mb_x < mb_width; mb_x++)
219
3816050
            ljpeg_encode_yuv_mb(s, pb, frame, s->pred, mb_x, mb_y);
220
    }
221
222
200
    return 0;
223
}
224
225
200
static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
226
                              const AVFrame *pict, int *got_packet)
227
{
228
200
    LJpegEncContext *s = avctx->priv_data;
229
    PutBitContext pb;
230
200
    const int width  = avctx->width;
231
200
    const int height = avctx->height;
232
200
    const int mb_width  = (width  + s->hsample[0] - 1) / s->hsample[0];
233
200
    const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0];
234
200
    int max_pkt_size = AV_INPUT_BUFFER_MIN_SIZE;
235
    int ret, header_bits;
236
237
200
    if(    avctx->pix_fmt == AV_PIX_FMT_BGR0
238
200
        || avctx->pix_fmt == AV_PIX_FMT_BGR24)
239
        max_pkt_size += width * height * 3 * 4;
240
200
    else if(avctx->pix_fmt == AV_PIX_FMT_BGRA)
241
        max_pkt_size += width * height * 4 * 4;
242
    else {
243
200
        max_pkt_size += mb_width * mb_height * 3 * 4
244
200
                        * s->hsample[0] * s->vsample[0];
245
    }
246
247
200
    if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size, 0)) < 0)
248
        return ret;
249
250
200
    init_put_bits(&pb, pkt->data, pkt->size);
251
252
200
    ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable,
253
200
                                   s->pred, s->matrix, s->matrix);
254
255
200
    header_bits = put_bits_count(&pb);
256
257
200
    if(    avctx->pix_fmt == AV_PIX_FMT_BGR0
258
200
        || avctx->pix_fmt == AV_PIX_FMT_BGRA
259
200
        || avctx->pix_fmt == AV_PIX_FMT_BGR24)
260
        ret = ljpeg_encode_bgr(avctx, &pb, pict);
261
    else
262
200
        ret = ljpeg_encode_yuv(avctx, &pb, pict);
263
200
    if (ret < 0)
264
        return ret;
265
266
200
    emms_c();
267
268
200
    ff_mjpeg_escape_FF(&pb, header_bits >> 3);
269
200
    ff_mjpeg_encode_picture_trailer(&pb, header_bits);
270
271
200
    flush_put_bits(&pb);
272
200
    pkt->size   = put_bits_ptr(&pb) - pb.buf;
273
200
    pkt->flags |= AV_PKT_FLAG_KEY;
274
200
    *got_packet = 1;
275
276
200
    return 0;
277
}
278
279
4
static av_cold int ljpeg_encode_close(AVCodecContext *avctx)
280
{
281
4
    LJpegEncContext *s = avctx->priv_data;
282
283
4
    av_freep(&s->scratch);
284
285
4
    return 0;
286
}
287
288
4
static av_cold int ljpeg_encode_init(AVCodecContext *avctx)
289
{
290
4
    LJpegEncContext *s = avctx->priv_data;
291
292
4
    if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
293
         avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
294
         avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
295
         avctx->color_range == AVCOL_RANGE_MPEG) &&
296
4
        avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
297
        av_log(avctx, AV_LOG_ERROR,
298
               "Limited range YUV is non-standard, set strict_std_compliance to "
299
               "at least unofficial to use it.\n");
300
        return AVERROR(EINVAL);
301
    }
302
303
#if FF_API_CODED_FRAME
304
FF_DISABLE_DEPRECATION_WARNINGS
305
4
    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
306
4
    avctx->coded_frame->key_frame = 1;
307
FF_ENABLE_DEPRECATION_WARNINGS
308
#endif
309
310
4
    s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch));
311
4
    if (!s->scratch)
312
        goto fail;
313
314
4
    ff_idctdsp_init(&s->idsp, avctx);
315
4
    ff_init_scantable(s->idsp.idct_permutation, &s->scantable,
316
                      ff_zigzag_direct);
317
318
4
    ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample);
319
320
4
    ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,
321
4
                                 s->huff_code_dc_luminance,
322
                                 avpriv_mjpeg_bits_dc_luminance,
323
                                 avpriv_mjpeg_val_dc);
324
4
    ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance,
325
4
                                 s->huff_code_dc_chrominance,
326
                                 avpriv_mjpeg_bits_dc_chrominance,
327
                                 avpriv_mjpeg_val_dc);
328
329
4
    return 0;
330
fail:
331
    ljpeg_encode_close(avctx);
332
    return AVERROR(ENOMEM);
333
}
334
335
#define OFFSET(x) offsetof(LJpegEncContext, x)
336
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
337
static const AVOption options[] = {
338
{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 3, VE, "pred" },
339
    { "left",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" },
340
    { "plane",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" },
341
    { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "pred" },
342
343
    { NULL},
344
};
345
346
static const AVClass ljpeg_class = {
347
    .class_name = "ljpeg",
348
    .item_name  = av_default_item_name,
349
    .option     = options,
350
    .version    = LIBAVUTIL_VERSION_INT,
351
};
352
353
AVCodec ff_ljpeg_encoder = {
354
    .name           = "ljpeg",
355
    .long_name      = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
356
    .type           = AVMEDIA_TYPE_VIDEO,
357
    .id             = AV_CODEC_ID_LJPEG,
358
    .priv_data_size = sizeof(LJpegEncContext),
359
    .priv_class     = &ljpeg_class,
360
    .init           = ljpeg_encode_init,
361
    .encode2        = ljpeg_encode_frame,
362
    .close          = ljpeg_encode_close,
363
    .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
364
    .pix_fmts       = (const enum AVPixelFormat[]){
365
        AV_PIX_FMT_BGR24   , AV_PIX_FMT_BGRA    , AV_PIX_FMT_BGR0,
366
        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
367
        AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P,
368
        AV_PIX_FMT_NONE},
369
};