FFmpeg
Loading...
Searching...
No Matches
sunrastenc.c
Go to the documentation of this file.
1/*
2 * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image encoder
3 * Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@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
23#include "libavutil/opt.h"
24
25#include "avcodec.h"
26#include "bytestream.h"
27#include "codec_internal.h"
28#include "encode.h"
29#include "sunrast.h"
30
31typedef struct SUNRASTContext {
32 AVClass *class;
33
35 int depth; ///< depth of pixel
36 int length; ///< length (bytes) of image
37 int type; ///< type of file
38 int maptype; ///< type of colormap
39 int maplength; ///< length (bytes) of colormap
40 int size;
42
44{
45 SUNRASTContext *s = avctx->priv_data;
46
47 bytestream2_put_be32u(&s->p, RAS_MAGIC);
48 bytestream2_put_be32u(&s->p, avctx->width);
49 bytestream2_put_be32u(&s->p, avctx->height);
50 bytestream2_put_be32u(&s->p, s->depth);
51 bytestream2_put_be32u(&s->p, s->length);
52 bytestream2_put_be32u(&s->p, s->type);
53 bytestream2_put_be32u(&s->p, s->maptype);
54 bytestream2_put_be32u(&s->p, s->maplength);
55}
56
58 const uint8_t *pixels,
59 const uint32_t *palette_data,
60 int linesize)
61{
62 SUNRASTContext *s = avctx->priv_data;
63 const uint8_t *ptr;
64 int len, alen, x, y;
65
66 if (s->maplength) { // palettized
67 PutByteContext pb_r, pb_g;
68 int len = s->maplength / 3;
69
70 pb_r = s->p;
72 pb_g = s->p;
74
75 for (x = 0; x < len; x++) {
76 uint32_t pixel = palette_data[x];
77
78 bytestream2_put_byteu(&pb_r, (pixel >> 16) & 0xFF);
79 bytestream2_put_byteu(&pb_g, (pixel >> 8) & 0xFF);
80 bytestream2_put_byteu(&s->p, pixel & 0xFF);
81 }
82 }
83
84 len = (s->depth * avctx->width + 7) >> 3;
85 alen = len + (len & 1);
86 ptr = pixels;
87
88 if (s->type == RT_BYTE_ENCODED) {
89 uint8_t value, value2;
90 int run;
91
92 ptr = pixels;
93
94#define GET_VALUE y >= avctx->height ? 0 : x >= len ? ptr[len-1] : ptr[x]
95
96 x = 0, y = 0;
97 value2 = GET_VALUE;
98 while (y < avctx->height) {
99 run = 1;
100 value = value2;
101 x++;
102 if (x >= alen) {
103 x = 0;
104 ptr += linesize, y++;
105 }
106
107 value2 = GET_VALUE;
108 while (value2 == value && run < 256 && y < avctx->height) {
109 x++;
110 run++;
111 if (x >= alen) {
112 x = 0;
113 ptr += linesize, y++;
114 }
115 value2 = GET_VALUE;
116 }
117
118 if (run > 2 || value == RLE_TRIGGER) {
119 bytestream2_put_byteu(&s->p, RLE_TRIGGER);
120 bytestream2_put_byteu(&s->p, run - 1);
121 if (run > 1)
122 bytestream2_put_byteu(&s->p, value);
123 } else if (run == 1) {
124 bytestream2_put_byteu(&s->p, value);
125 } else
126 bytestream2_put_be16u(&s->p, (value << 8) | value);
127 }
128
129 // update data length for header
130 s->length = bytestream2_tell_p(&s->p) - 32 - s->maplength;
131 } else {
132 for (y = 0; y < avctx->height; y++) {
133 bytestream2_put_buffer(&s->p, ptr, len);
134 if (len < alen)
135 bytestream2_put_byteu(&s->p, 0);
136 ptr += linesize;
137 }
138 }
139}
140
142{
143 SUNRASTContext *s = avctx->priv_data;
144
145 // adjust boolean option to RT equivalent
146 s->type++;
147
148 s->maptype = RMT_NONE;
149 s->maplength = 0;
150
151 switch (avctx->pix_fmt) {
153 s->depth = 1;
154 break;
155 case AV_PIX_FMT_PAL8 :
156 s->maptype = RMT_EQUAL_RGB;
157 s->maplength = 3 * 256;
159 case AV_PIX_FMT_GRAY8:
160 s->depth = 8;
161 break;
162 case AV_PIX_FMT_BGR24:
163 s->depth = 24;
164 break;
165 default:
166 return AVERROR_BUG;
167 }
168 s->length = avctx->height * (FFALIGN(avctx->width * s->depth, 16) >> 3);
169 s->size = 32 + s->maplength + s->length * s->type;
170
171 return 0;
172}
173
175 const AVFrame *frame, int *got_packet_ptr)
176{
177 SUNRASTContext *s = avctx->priv_data;
178 int ret;
179
180 if ((ret = ff_alloc_packet(avctx, avpkt, s->size)) < 0)
181 return ret;
182
183 bytestream2_init_writer(&s->p, avpkt->data, avpkt->size);
185 sunrast_image_write_image(avctx, frame->data[0],
186 (const uint32_t *)frame->data[1],
187 frame->linesize[0]);
188 // update data length in header after RLE
189 if (s->type == RT_BYTE_ENCODED)
190 AV_WB32(&avpkt->data[16], s->length);
191
192 *got_packet_ptr = 1;
193 avpkt->size = bytestream2_tell_p(&s->p);
194 return 0;
195}
196
197#define OFFSET(x) offsetof(SUNRASTContext, x)
198#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
199static const AVOption options[] = {
200 { "rle", "Use run-length compression", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
201
202 { NULL },
203};
204
205static const AVClass sunrast_class = {
206 .class_name = "sunrast",
207 .item_name = av_default_item_name,
208 .option = options,
209 .version = LIBAVUTIL_VERSION_INT,
210};
211
213 .p.name = "sunrast",
214 CODEC_LONG_NAME("Sun Rasterfile image"),
215 .p.type = AVMEDIA_TYPE_VIDEO,
216 .p.id = AV_CODEC_ID_SUNRAST,
218 .priv_data_size = sizeof(SUNRASTContext),
221 .p.priv_class = &sunrast_class,
226};
const FFCodec ff_sunrast_encoder
Definition sunrastenc.c:212
#define VE
Definition amfenc_av1.c:30
Libavcodec external API header.
#define pixel
static av_always_inline int bytestream2_tell_p(const PutByteContext *p)
Definition bytestream.h:197
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition bytestream.h:147
static av_always_inline void bytestream2_skip_p(PutByteContext *p, unsigned int size)
Definition bytestream.h:180
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition bytestream.h:286
#define s(width, name)
Definition cbs_vp9.c:198
#define CODEC_PIXFMTS(...)
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define NULL
Definition coverity.c:32
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition encode.c:62
double value
Definition eval.c:102
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_SUNRAST
Definition codec_id.h:160
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
cl_device_type type
#define AV_WB32(p, v)
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define av_cold
Definition attributes.h:117
#define FFALIGN(x, a)
Definition macros.h:78
AVOptions.
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition pixfmt.h:84
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition pixfmt.h:82
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
PutByteContext p
Definition sunrastenc.c:34
int maptype
type of colormap
Definition sunrastenc.c:38
int maplength
length (bytes) of colormap
Definition sunrastenc.c:39
int type
type of file
Definition sunrastenc.c:37
int length
length (bytes) of image
Definition sunrastenc.c:36
int depth
depth of pixel
Definition sunrastenc.c:35
#define RAS_MAGIC
Definition sunrast.h:25
#define RT_BYTE_ENCODED
Definition sunrast.h:38
#define RMT_EQUAL_RGB
Definition sunrast.h:28
#define RMT_NONE
Definition sunrast.h:27
#define RLE_TRIGGER
Definition sunrast.h:39
static int sunrast_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition sunrastenc.c:174
static void sunrast_image_write_header(AVCodecContext *avctx)
Definition sunrastenc.c:43
static av_cold int sunrast_encode_init(AVCodecContext *avctx)
Definition sunrastenc.c:141
static void sunrast_image_write_image(AVCodecContext *avctx, const uint8_t *pixels, const uint32_t *palette_data, int linesize)
Definition sunrastenc.c:57
static const AVClass sunrast_class
Definition sunrastenc.c:205
#define OFFSET(x)
Definition sunrastenc.c:197
#define GET_VALUE
uint8_t run
Definition svq3.c:207
#define height
Definition dsp.h:89
int len