Mercurial > libavcodec.hg
annotate sgienc.c @ 11557:53822d92c3f7 libavcodec
Make sure the EC code does not attempt to use inter based concealment if there
is no reference frame available. (this can happen because the EC code will attempt
to use reference frames even for I/IDR frames)
author | michael |
---|---|
date | Tue, 30 Mar 2010 20:46:46 +0000 |
parents | 5f263438d11b |
children | 8a4984c5cacc |
rev | line source |
---|---|
4790 | 1 /* |
2 * SGI image encoder | |
3 * Todd Kirby <doubleshot@pacbell.net> | |
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 "avcodec.h" | |
23 #include "bytestream.h" | |
24 #include "sgi.h" | |
25 #include "rle.h" | |
26 | |
27 #define SGI_SINGLE_CHAN 2 | |
28 #define SGI_MULTI_CHAN 3 | |
29 | |
30 typedef struct SgiContext { | |
31 AVFrame picture; | |
32 } SgiContext; | |
33 | |
10338 | 34 static av_cold int encode_init(AVCodecContext *avctx) |
35 { | |
4790 | 36 SgiContext *s = avctx->priv_data; |
37 | |
38 avcodec_get_frame_defaults(&s->picture); | |
39 avctx->coded_frame = &s->picture; | |
40 | |
41 return 0; | |
42 } | |
43 | |
44 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, | |
10338 | 45 int buf_size, void *data) |
46 { | |
4790 | 47 SgiContext *s = avctx->priv_data; |
48 AVFrame * const p = &s->picture; | |
49 uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf; | |
50 int x, y, z, length, tablesize; | |
51 unsigned int width, height, depth, dimension; | |
52 unsigned char *orig_buf = buf, *end_buf = buf + buf_size; | |
53 | |
54 *p = *(AVFrame*)data; | |
55 p->pict_type = FF_I_TYPE; | |
56 p->key_frame = 1; | |
57 | |
10338 | 58 width = avctx->width; |
4790 | 59 height = avctx->height; |
60 | |
61 switch (avctx->pix_fmt) { | |
10338 | 62 case PIX_FMT_GRAY8: |
63 dimension = SGI_SINGLE_CHAN; | |
64 depth = SGI_GRAYSCALE; | |
65 break; | |
66 case PIX_FMT_RGB24: | |
67 dimension = SGI_MULTI_CHAN; | |
68 depth = SGI_RGB; | |
69 break; | |
70 case PIX_FMT_RGBA: | |
71 dimension = SGI_MULTI_CHAN; | |
72 depth = SGI_RGBA; | |
73 break; | |
74 default: | |
75 return AVERROR_INVALIDDATA; | |
4790 | 76 } |
77 | |
78 tablesize = depth * height * 4; | |
79 length = tablesize * 2 + SGI_HEADER_SIZE; | |
80 | |
81 if (buf_size < length) { | |
82 av_log(avctx, AV_LOG_ERROR, "buf_size too small(need %d, got %d)\n", length, buf_size); | |
83 return -1; | |
84 } | |
85 | |
86 /* Encode header. */ | |
87 bytestream_put_be16(&buf, SGI_MAGIC); | |
10330
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
88 bytestream_put_byte(&buf, avctx->coder_type != FF_CODER_TYPE_RAW); /* RLE 1 - VERBATIM 0*/ |
4790 | 89 bytestream_put_byte(&buf, 1); /* bytes_per_channel */ |
90 bytestream_put_be16(&buf, dimension); | |
91 bytestream_put_be16(&buf, width); | |
92 bytestream_put_be16(&buf, height); | |
93 bytestream_put_be16(&buf, depth); | |
94 | |
95 /* The rest are constant in this implementation. */ | |
96 bytestream_put_be32(&buf, 0L); /* pixmin */ | |
97 bytestream_put_be32(&buf, 255L); /* pixmax */ | |
98 bytestream_put_be32(&buf, 0L); /* dummy */ | |
99 | |
100 /* name */ | |
101 memset(buf, 0, SGI_HEADER_SIZE); | |
102 buf += 80; | |
103 | |
104 /* colormap */ | |
105 bytestream_put_be32(&buf, 0L); | |
106 | |
107 /* The rest of the 512 byte header is unused. */ | |
108 buf += 404; | |
109 offsettab = buf; | |
110 | |
10330
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
111 if (avctx->coder_type != FF_CODER_TYPE_RAW) { |
10338 | 112 /* Skip RLE offset table. */ |
113 buf += tablesize; | |
114 lengthtab = buf; | |
4790 | 115 |
10338 | 116 /* Skip RLE length table. */ |
117 buf += tablesize; | |
4790 | 118 |
10338 | 119 /* Make an intermediate consecutive buffer. */ |
10339
a352df49a10f
Use "!exp" instead of "exp == NULL" in if condition.
diego
parents:
10338
diff
changeset
|
120 if (!(encode_buf = av_malloc(width))) |
10338 | 121 return -1; |
4790 | 122 |
10330
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
123 for (z = 0; z < depth; z++) { |
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
124 in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; |
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
125 |
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
126 for (y = 0; y < height; y++) { |
10338 | 127 bytestream_put_be32(&offsettab, buf - orig_buf); |
128 | |
129 for (x = 0; x < width; x++) | |
130 encode_buf[x] = in_buf[depth * x]; | |
10330
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
131 |
10338 | 132 if ((length = ff_rle_encode(buf, end_buf - buf - 1, encode_buf, 1, width, 0, 0, 0x80, 0)) < 1) { |
133 av_free(encode_buf); | |
134 return -1; | |
135 } | |
136 | |
137 buf += length; | |
138 bytestream_put_byte(&buf, 0); | |
139 bytestream_put_be32(&lengthtab, length + 1); | |
10330
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
140 in_buf -= p->linesize[0]; |
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
141 } |
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
142 } |
10338 | 143 |
144 av_free(encode_buf); | |
10340 | 145 } else { |
146 for (z = 0; z < depth; z++) { | |
147 in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; | |
10338 | 148 |
10340 | 149 for (y = 0; y < height; y++) { |
150 for (x = 0; x < width * depth; x += depth) | |
151 bytestream_put_byte(&buf, in_buf[x]); | |
10338 | 152 |
10340 | 153 in_buf -= p->linesize[0]; |
10338 | 154 } |
155 } | |
10340 | 156 } |
10330
ac0b95400577
Add support for SGI images without RLE compression.
diego
parents:
10146
diff
changeset
|
157 |
4790 | 158 /* total length */ |
159 return buf - orig_buf; | |
160 } | |
161 | |
162 AVCodec sgi_encoder = { | |
163 "sgi", | |
164 CODEC_TYPE_VIDEO, | |
165 CODEC_ID_SGI, | |
166 sizeof(SgiContext), | |
167 encode_init, | |
168 encode_frame, | |
169 NULL, | |
10146
38cfe222e1a4
Mark all pix_fmts and supported_framerates compound literals as const.
reimar
parents:
9624
diff
changeset
|
170 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_GRAY8, PIX_FMT_NONE}, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6788
diff
changeset
|
171 .long_name= NULL_IF_CONFIG_SMALL("SGI image"), |
4790 | 172 }; |