/src/ffmpeg/libavcodec/aliaspixenc.c
Line | Count | Source |
1 | | /* |
2 | | * Alias PIX image encoder |
3 | | * Copyright (C) 2014 Vittorio Giovara <vittorio.giovara@gmail.com> |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * FFmpeg is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | #include "libavutil/intreadwrite.h" |
23 | | |
24 | | #include "avcodec.h" |
25 | | #include "bytestream.h" |
26 | | #include "codec_internal.h" |
27 | | #include "encode.h" |
28 | | |
29 | 14.2k | #define ALIAS_HEADER_SIZE 10 |
30 | | |
31 | | static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
32 | | const AVFrame *frame, int *got_packet) |
33 | 7.10k | { |
34 | 7.10k | int width, height, bits_pixel, length, ret; |
35 | 7.10k | uint8_t *buf; |
36 | | |
37 | 7.10k | width = avctx->width; |
38 | 7.10k | height = avctx->height; |
39 | | |
40 | 7.10k | if (width > 65535 || height > 65535 || |
41 | 7.10k | width * height >= INT_MAX / 4 - ALIAS_HEADER_SIZE) { |
42 | 0 | av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n", width, height); |
43 | 0 | return AVERROR_INVALIDDATA; |
44 | 0 | } |
45 | | |
46 | 7.10k | switch (avctx->pix_fmt) { |
47 | 6.81k | case AV_PIX_FMT_GRAY8: |
48 | 6.81k | bits_pixel = 8; |
49 | 6.81k | break; |
50 | 298 | case AV_PIX_FMT_BGR24: |
51 | 298 | bits_pixel = 24; |
52 | 298 | break; |
53 | 0 | default: |
54 | 0 | return AVERROR(EINVAL); |
55 | 7.10k | } |
56 | | |
57 | 7.10k | length = ALIAS_HEADER_SIZE + 4 * width * height; // max possible |
58 | 7.10k | if ((ret = ff_alloc_packet(avctx, pkt, length)) < 0) |
59 | 0 | return ret; |
60 | | |
61 | 7.10k | buf = pkt->data; |
62 | | |
63 | | /* Encode header. */ |
64 | 7.10k | bytestream_put_be16(&buf, width); |
65 | 7.10k | bytestream_put_be16(&buf, height); |
66 | 7.10k | bytestream_put_be32(&buf, 0); /* X, Y offset */ |
67 | 7.10k | bytestream_put_be16(&buf, bits_pixel); |
68 | | |
69 | 2.50M | for (int j = 0, bytes_pixel = bits_pixel >> 3; j < height; j++) { |
70 | 2.49M | const uint8_t *in_buf = frame->data[0] + frame->linesize[0] * j; |
71 | 2.49M | const uint8_t *const line_end = in_buf + bytes_pixel * width; |
72 | 5.66M | while (in_buf < line_end) { |
73 | 3.17M | int count = 0; |
74 | 3.17M | int pixel; |
75 | | |
76 | 3.17M | if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) { |
77 | 1.01M | pixel = *in_buf; |
78 | 5.27M | while (count < 255 && in_buf < line_end && pixel == *in_buf) { |
79 | 4.26M | count++; |
80 | 4.26M | in_buf++; |
81 | 4.26M | } |
82 | 1.01M | bytestream_put_byte(&buf, count); |
83 | 1.01M | bytestream_put_byte(&buf, pixel); |
84 | 2.16M | } else { /* AV_PIX_FMT_BGR24 */ |
85 | 2.16M | pixel = AV_RB24(in_buf); |
86 | 11.2M | while (count < 255 && in_buf < line_end && |
87 | 9.34M | pixel == AV_RB24(in_buf)) { |
88 | 9.06M | count++; |
89 | 9.06M | in_buf += 3; |
90 | 9.06M | } |
91 | 2.16M | bytestream_put_byte(&buf, count); |
92 | 2.16M | bytestream_put_be24(&buf, pixel); |
93 | 2.16M | } |
94 | 3.17M | } |
95 | 2.49M | } |
96 | | |
97 | | /* Total length */ |
98 | 7.10k | av_shrink_packet(pkt, buf - pkt->data); |
99 | 7.10k | *got_packet = 1; |
100 | | |
101 | 7.10k | return 0; |
102 | 7.10k | } |
103 | | |
104 | | const FFCodec ff_alias_pix_encoder = { |
105 | | .p.name = "alias_pix", |
106 | | CODEC_LONG_NAME("Alias/Wavefront PIX image"), |
107 | | .p.type = AVMEDIA_TYPE_VIDEO, |
108 | | .p.id = AV_CODEC_ID_ALIAS_PIX, |
109 | | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, |
110 | | FF_CODEC_ENCODE_CB(encode_frame), |
111 | | CODEC_PIXFMTS(AV_PIX_FMT_BGR24, AV_PIX_FMT_GRAY8), |
112 | | }; |