FFmpeg
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 
22 #include "libavutil/opt.h"
23 
24 #include "avcodec.h"
25 #include "bytestream.h"
26 #include "codec_internal.h"
27 #include "encode.h"
28 #include "sunrast.h"
29 
30 typedef struct SUNRASTContext {
31  AVClass *class;
32 
34  int depth; ///< depth of pixel
35  int length; ///< length (bytes) of image
36  int type; ///< type of file
37  int maptype; ///< type of colormap
38  int maplength; ///< length (bytes) of colormap
39  int size;
41 
43 {
44  SUNRASTContext *s = avctx->priv_data;
45 
46  bytestream2_put_be32u(&s->p, RAS_MAGIC);
47  bytestream2_put_be32u(&s->p, avctx->width);
48  bytestream2_put_be32u(&s->p, avctx->height);
49  bytestream2_put_be32u(&s->p, s->depth);
50  bytestream2_put_be32u(&s->p, s->length);
51  bytestream2_put_be32u(&s->p, s->type);
52  bytestream2_put_be32u(&s->p, s->maptype);
53  bytestream2_put_be32u(&s->p, s->maplength);
54 }
55 
57  const uint8_t *pixels,
58  const uint32_t *palette_data,
59  int linesize)
60 {
61  SUNRASTContext *s = avctx->priv_data;
62  const uint8_t *ptr;
63  int len, alen, x, y;
64 
65  if (s->maplength) { // palettized
66  PutByteContext pb_r, pb_g;
67  int len = s->maplength / 3;
68 
69  pb_r = s->p;
70  bytestream2_skip_p(&s->p, len);
71  pb_g = s->p;
72  bytestream2_skip_p(&s->p, len);
73 
74  for (x = 0; x < len; x++) {
75  uint32_t pixel = palette_data[x];
76 
77  bytestream2_put_byteu(&pb_r, (pixel >> 16) & 0xFF);
78  bytestream2_put_byteu(&pb_g, (pixel >> 8) & 0xFF);
79  bytestream2_put_byteu(&s->p, pixel & 0xFF);
80  }
81  }
82 
83  len = (s->depth * avctx->width + 7) >> 3;
84  alen = len + (len & 1);
85  ptr = pixels;
86 
87  if (s->type == RT_BYTE_ENCODED) {
88  uint8_t value, value2;
89  int run;
90 
91  ptr = pixels;
92 
93 #define GET_VALUE y >= avctx->height ? 0 : x >= len ? ptr[len-1] : ptr[x]
94 
95  x = 0, y = 0;
96  value2 = GET_VALUE;
97  while (y < avctx->height) {
98  run = 1;
99  value = value2;
100  x++;
101  if (x >= alen) {
102  x = 0;
103  ptr += linesize, y++;
104  }
105 
106  value2 = GET_VALUE;
107  while (value2 == value && run < 256 && y < avctx->height) {
108  x++;
109  run++;
110  if (x >= alen) {
111  x = 0;
112  ptr += linesize, y++;
113  }
114  value2 = GET_VALUE;
115  }
116 
117  if (run > 2 || value == RLE_TRIGGER) {
118  bytestream2_put_byteu(&s->p, RLE_TRIGGER);
119  bytestream2_put_byteu(&s->p, run - 1);
120  if (run > 1)
121  bytestream2_put_byteu(&s->p, value);
122  } else if (run == 1) {
123  bytestream2_put_byteu(&s->p, value);
124  } else
125  bytestream2_put_be16u(&s->p, (value << 8) | value);
126  }
127 
128  // update data length for header
129  s->length = bytestream2_tell_p(&s->p) - 32 - s->maplength;
130  } else {
131  for (y = 0; y < avctx->height; y++) {
132  bytestream2_put_buffer(&s->p, ptr, len);
133  if (len < alen)
134  bytestream2_put_byteu(&s->p, 0);
135  ptr += linesize;
136  }
137  }
138 }
139 
141 {
142  SUNRASTContext *s = avctx->priv_data;
143 
144  // adjust boolean option to RT equivalent
145  s->type++;
146 
147  s->maptype = RMT_NONE;
148  s->maplength = 0;
149 
150  switch (avctx->pix_fmt) {
152  s->depth = 1;
153  break;
154  case AV_PIX_FMT_PAL8 :
155  s->maptype = RMT_EQUAL_RGB;
156  s->maplength = 3 * 256;
157  /* fall-through */
158  case AV_PIX_FMT_GRAY8:
159  s->depth = 8;
160  break;
161  case AV_PIX_FMT_BGR24:
162  s->depth = 24;
163  break;
164  default:
165  return AVERROR_BUG;
166  }
167  s->length = avctx->height * (FFALIGN(avctx->width * s->depth, 16) >> 3);
168  s->size = 32 + s->maplength + s->length * s->type;
169 
170  return 0;
171 }
172 
173 static int sunrast_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
174  const AVFrame *frame, int *got_packet_ptr)
175 {
176  SUNRASTContext *s = avctx->priv_data;
177  int ret;
178 
179  if ((ret = ff_alloc_packet(avctx, avpkt, s->size)) < 0)
180  return ret;
181 
182  bytestream2_init_writer(&s->p, avpkt->data, avpkt->size);
185  (const uint32_t *)frame->data[1],
186  frame->linesize[0]);
187  // update data length in header after RLE
188  if (s->type == RT_BYTE_ENCODED)
189  AV_WB32(&avpkt->data[16], s->length);
190 
191  *got_packet_ptr = 1;
192  avpkt->size = bytestream2_tell_p(&s->p);
193  return 0;
194 }
195 
196 #define OFFSET(x) offsetof(SUNRASTContext, x)
197 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
198 static const AVOption options[] = {
199  { "rle", "Use run-length compression", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
200 
201  { NULL },
202 };
203 
204 static const AVClass sunrast_class = {
205  .class_name = "sunrast",
206  .item_name = av_default_item_name,
207  .option = options,
208  .version = LIBAVUTIL_VERSION_INT,
209 };
210 
212  .p.name = "sunrast",
213  CODEC_LONG_NAME("Sun Rasterfile image"),
214  .p.type = AVMEDIA_TYPE_VIDEO,
215  .p.id = AV_CODEC_ID_SUNRAST,
217  .priv_data_size = sizeof(SUNRASTContext),
220  .p.priv_class = &sunrast_class,
221  .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24,
225  AV_PIX_FMT_NONE },
226 };
SUNRASTContext::p
PutByteContext p
Definition: sunrastenc.c:33
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
opt.h
RMT_EQUAL_RGB
#define RMT_EQUAL_RGB
Definition: sunrast.h:28
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
ff_sunrast_encoder
const FFCodec ff_sunrast_encoder
Definition: sunrastenc.c:211
SUNRASTContext::length
int length
length (bytes) of image
Definition: sunrastenc.c:35
AVPacket::data
uint8_t * data
Definition: packet.h:522
AVOption
AVOption.
Definition: opt.h:346
encode.h
bytestream2_tell_p
static av_always_inline int bytestream2_tell_p(PutByteContext *p)
Definition: bytestream.h:197
AV_PIX_FMT_MONOWHITE
@ 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
FFCodec
Definition: codec_internal.h:127
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
sunrast_image_write_header
static void sunrast_image_write_header(AVCodecContext *avctx)
Definition: sunrastenc.c:42
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
options
static const AVOption options[]
Definition: sunrastenc.c:198
SUNRASTContext::type
int type
type of file
Definition: sunrastenc.c:36
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:296
av_cold
#define av_cold
Definition: attributes.h:90
sunrast_image_write_image
static void sunrast_image_write_image(AVCodecContext *avctx, const uint8_t *pixels, const uint32_t *palette_data, int linesize)
Definition: sunrastenc.c:56
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
GET_VALUE
#define GET_VALUE
s
#define s(width, name)
Definition: cbs_vp9.c:198
SUNRASTContext
Definition: sunrastenc.c:30
bytestream2_put_buffer
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:286
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
#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:159
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
frame
static AVFrame * frame
Definition: demux_decode.c:54
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:203
pixel
uint8_t pixel
Definition: tiny_ssim.c:41
SUNRASTContext::depth
int depth
depth of pixel
Definition: sunrastenc.c:34
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
sunrast.h
sunrast_encode_init
static av_cold int sunrast_encode_init(AVCodecContext *avctx)
Definition: sunrastenc.c:140
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
RMT_NONE
#define RMT_NONE
Definition: sunrast.h:27
OFFSET
#define OFFSET(x)
Definition: sunrastenc.c:196
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:417
PutByteContext
Definition: bytestream.h:37
VE
#define VE
Definition: sunrastenc.c:197
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:523
codec_internal.h
height
#define height
RLE_TRIGGER
#define RLE_TRIGGER
Definition: sunrast.h:39
sunrast_encode_frame
static int sunrast_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: sunrastenc.c:173
bytestream2_skip_p
static av_always_inline void bytestream2_skip_p(PutByteContext *p, unsigned int size)
Definition: bytestream.h:180
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
len
int len
Definition: vorbis_enc_data.h:426
AVCodecContext::height
int height
Definition: avcodec.h:618
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:657
avcodec.h
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
sunrast_class
static const AVClass sunrast_class
Definition: sunrastenc.c:204
SUNRASTContext::maptype
int maptype
type of colormap
Definition: sunrastenc.c:37
AVCodecContext
main external API structure.
Definition: avcodec.h:445
SUNRASTContext::size
int size
Definition: sunrastenc.c:39
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
RT_BYTE_ENCODED
#define RT_BYTE_ENCODED
Definition: sunrast.h:38
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:499
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
bytestream.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:385
AV_CODEC_ID_SUNRAST
@ AV_CODEC_ID_SUNRAST
Definition: codec_id.h:162
RAS_MAGIC
#define RAS_MAGIC
Definition: sunrast.h:25
SUNRASTContext::maplength
int maplength
length (bytes) of colormap
Definition: sunrastenc.c:38
ff_alloc_packet
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition: encode.c:61