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/opt.h" 36#include "libavutil/pixdesc.h" 37 38#include "avcodec.h" 39#include "codec_internal.h" 40#include "encode.h" 41#include "idctdsp.h" 42#include "jpegtables.h" 43#include "mathops.h" 44#include "mjpegenc_common.h" 45#include "mjpeg.h" 46 47typedef struct LJpegEncContext { 48 AVClass *class; 49 IDCTDSPContext idsp; 50 ScanTable scantable; 51 uint16_t matrix[64]; 52 53 int vsample[4]; 54 int hsample[4]; 55 56 uint16_t huff_code_dc_luminance[12]; 57 uint16_t huff_code_dc_chrominance[12]; 58 uint8_t huff_size_dc_luminance[12]; 59 uint8_t huff_size_dc_chrominance[12]; 60 61 uint16_t (*scratch)[4]; 62 int pred; 63} LJpegEncContext; 64 65static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb, 66 const AVFrame *frame) 67{ 68 LJpegEncContext *s = avctx->priv_data; 69 const int width = frame->width; 70 const int height = frame->height; 71 const int linesize = frame->linesize[0]; 72 uint16_t (*buffer)[4] = s->scratch; 73 int left[4], top[4], topleft[4]; 74 int x, y, i; 75 76 for (i = 0; i < 4; i++) 77 buffer[0][i] = 1 << (9 - 1); 78 79 for (y = 0; y < height; y++) { 80 const int modified_predictor = y ? s->pred : 1; 81 uint8_t *ptr = frame->data[0] + (linesize * y); 82 83 if (put_bytes_left(pb, 0) < width * 4 * 4) { 84 av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); 85 return -1; 86 } 87 88 for (i = 0; i < 4; i++) 89 top[i]= left[i]= topleft[i]= buffer[0][i]; 90 91 for (x = 0; x < width; x++) { 92 if(avctx->pix_fmt == AV_PIX_FMT_BGR24){ 93 buffer[x][1] = ptr[3 * x + 0] - ptr[3 * x + 1] + 0x100; 94 buffer[x][2] = ptr[3 * x + 2] - ptr[3 * x + 1] + 0x100; 95 buffer[x][0] = (ptr[3 * x + 0] + 2 * ptr[3 * x + 1] + ptr[3 * x + 2]) >> 2; 96 }else{ 97 buffer[x][1] = ptr[4 * x + 0] - ptr[4 * x + 1] + 0x100; 98 buffer[x][2] = ptr[4 * x + 2] - ptr[4 * x + 1] + 0x100; 99 buffer[x][0] = (ptr[4 * x + 0] + 2 * ptr[4 * x + 1] + ptr[4 * x + 2]) >> 2; 100 if (avctx->pix_fmt == AV_PIX_FMT_BGRA) 101 buffer[x][3] = ptr[4 * x + 3]; 102 } 103 104 for (i = 0; i < 3 + (avctx->pix_fmt == AV_PIX_FMT_BGRA); i++) { 105 int pred, diff; 106 107 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); 108 109 topleft[i] = top[i]; 110 top[i] = buffer[x+1][i]; 111 112 left[i] = buffer[x][i]; 113 114 diff = ((left[i] - pred + 0x100) & 0x1FF) - 0x100; 115 116 if (i == 0 || i == 3) 117 ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly 118 else 119 ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); 120 } 121 } 122 } 123 124 return 0; 125} 126 127static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb, 128 const AVFrame *frame, int predictor, 129 int mb_x, int mb_y) 130{ 131 int i; 132 133 if (mb_x == 0 || mb_y == 0) { 134 for (i = 0; i < 3; i++) { 135 uint8_t *ptr; 136 int x, y, h, v, linesize; 137 h = s->hsample[i]; 138 v = s->vsample[i]; 139 linesize = frame->linesize[i]; 140 141 for (y = 0; y < v; y++) { 142 for (x = 0; x < h; x++) { 143 int pred; 144 145 ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap 146 if (y == 0 && mb_y == 0) { 147 if (x == 0 && mb_x == 0) 148 pred = 128; 149 else 150 pred = ptr[-1]; 151 } else { 152 if (x == 0 && mb_x == 0) { 153 pred = ptr[-linesize]; 154 } else { 155 PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], 156 ptr[-1], predictor); 157 } 158 } 159 160 if (i == 0) 161 ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly 162 else 163 ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); 164 } 165 } 166 } 167 } else { 168 for (i = 0; i < 3; i++) { 169 uint8_t *ptr; 170 int x, y, h, v, linesize; 171 h = s->hsample[i]; 172 v = s->vsample[i]; 173 linesize = frame->linesize[i]; 174 175 for (y = 0; y < v; y++) { 176 for (x = 0; x < h; x++) { 177 int pred; 178 179 ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap 180 PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], ptr[-1], predictor); 181 182 if (i == 0) 183 ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly 184 else 185 ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); 186 } 187 } 188 } 189 } 190} 191 192static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb, 193 const AVFrame *frame) 194{ 195 LJpegEncContext *s = avctx->priv_data; 196 const int mb_width = (avctx->width + s->hsample[0] - 1) / s->hsample[0]; 197 const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0]; 198 int mb_x, mb_y; 199 200 for (mb_y = 0; mb_y < mb_height; mb_y++) { 201 if (put_bytes_left(pb, 0) < 202 mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) { 203 av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); 204 return -1; 205 } 206 207 for (mb_x = 0; mb_x < mb_width; mb_x++) 208 ljpeg_encode_yuv_mb(s, pb, frame, s->pred, mb_x, mb_y); 209 } 210 211 return 0; 212} 213 214static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 215 const AVFrame *pict, int *got_packet) 216{ 217 LJpegEncContext *s = avctx->priv_data; 218 PutBitContext pb; 219 const int width = avctx->width; 220 const int height = avctx->height; 221 const int mb_width = (width + s->hsample[0] - 1) / s->hsample[0]; 222 const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0]; 223 size_t max_pkt_size = AV_INPUT_BUFFER_MIN_SIZE; 224 int ret, header_bits; 225 226 if( avctx->pix_fmt == AV_PIX_FMT_BGR0 227 || avctx->pix_fmt == AV_PIX_FMT_BGR24) 228 max_pkt_size += width * height * 3 * 4; 229 else if(avctx->pix_fmt == AV_PIX_FMT_BGRA) 230 max_pkt_size += width * height * 4 * 4; 231 else { 232 max_pkt_size += mb_width * mb_height * 3 * 4 233 * s->hsample[0] * s->vsample[0]; 234 } 235 236 if ((ret = ff_mjpeg_add_icc_profile_size(avctx, pict, &max_pkt_size)) < 0) 237 return ret; 238 if ((ret = ff_alloc_packet(avctx, pkt, max_pkt_size)) < 0) 239 return ret; 240 241 init_put_bits(&pb, pkt->data, pkt->size); 242 243 ff_mjpeg_encode_picture_header(avctx, &pb, pict, NULL, &s->scantable, 244 s->pred, s->matrix, s->matrix, 0); 245 246 header_bits = put_bits_count(&pb); 247 248 if( avctx->pix_fmt == AV_PIX_FMT_BGR0 249 || avctx->pix_fmt == AV_PIX_FMT_BGRA 250 || avctx->pix_fmt == AV_PIX_FMT_BGR24) 251 ret = ljpeg_encode_bgr(avctx, &pb, pict); 252 else 253 ret = ljpeg_encode_yuv(avctx, &pb, pict); 254 if (ret < 0) 255 return ret; 256 257 emms_c(); 258 259 ff_mjpeg_escape_FF(&pb, header_bits >> 3); 260 ff_mjpeg_encode_picture_trailer(&pb, header_bits); 261 262 flush_put_bits(&pb); 263 pkt->size = put_bits_ptr(&pb) - pb.buf; 264 *got_packet = 1; 265 266 return 0; 267} 268 269static av_cold int ljpeg_encode_close(AVCodecContext *avctx) 270{ 271 LJpegEncContext *s = avctx->priv_data; 272 273 av_freep(&s->scratch); 274 275 return 0; 276} 277 278static av_cold int ljpeg_encode_init(AVCodecContext *avctx) 279{ 280 int ret = ff_mjpeg_encode_check_pix_fmt(avctx); 281 LJpegEncContext *s = avctx->priv_data; 282 283 if (ret < 0) 284 return ret; 285 286 s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch)); 287 if (!s->scratch) 288 return AVERROR(ENOMEM); 289 290 ff_idctdsp_init(&s->idsp, avctx); 291 ff_init_scantable(s->idsp.idct_permutation, &s->scantable, 292 ff_zigzag_direct); 293 294 ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample); 295 296 ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance, 297 s->huff_code_dc_luminance, 298 ff_mjpeg_bits_dc_luminance, 299 ff_mjpeg_val_dc); 300 ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance, 301 s->huff_code_dc_chrominance, 302 ff_mjpeg_bits_dc_chrominance, 303 ff_mjpeg_val_dc); 304 305 return 0; 306} 307 308#define OFFSET(x) offsetof(LJpegEncContext, x) 309#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 310static const AVOption options[] = { 311{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 3, VE, "pred" }, 312 { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, 313 { "plane", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" }, 314 { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "pred" }, 315 316 { NULL}, 317}; 318 319static const AVClass ljpeg_class = { 320 .class_name = "ljpeg", 321 .item_name = av_default_item_name, 322 .option = options, 323 .version = LIBAVUTIL_VERSION_INT, 324}; 325 326const FFCodec ff_ljpeg_encoder = { 327 .p.name = "ljpeg", 328 .p.long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), 329 .p.type = AVMEDIA_TYPE_VIDEO, 330 .p.id = AV_CODEC_ID_LJPEG, 331 .priv_data_size = sizeof(LJpegEncContext), 332 .p.priv_class = &ljpeg_class, 333 .init = ljpeg_encode_init, 334 FF_CODEC_ENCODE_CB(ljpeg_encode_frame), 335 .close = ljpeg_encode_close, 336 .p.capabilities = AV_CODEC_CAP_FRAME_THREADS, 337 .p.pix_fmts = (const enum AVPixelFormat[]){ 338 AV_PIX_FMT_BGR24 , AV_PIX_FMT_BGRA , AV_PIX_FMT_BGR0, 339 AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, 340 AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P, 341 AV_PIX_FMT_NONE}, 342 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 343}; 344