Mercurial > libavcodec.hg
annotate sunrast.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | ffb3668ff7af |
children |
rev | line source |
---|---|
6084 | 1 /* |
2 * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image decoder | |
3 * Copyright (c) 2007, 2008 Ivo van Poorten | |
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 | |
8573
2acf0ae7b041
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
7040
diff
changeset
|
22 #include "libavutil/intreadwrite.h" |
12372
914f484bb476
Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents:
11560
diff
changeset
|
23 #include "libavcore/imgutils.h" |
6084 | 24 #include "avcodec.h" |
25 | |
26 #define RT_OLD 0 | |
27 #define RT_STANDARD 1 | |
28 #define RT_BYTE_ENCODED 2 | |
29 #define RT_FORMAT_RGB 3 | |
30 #define RT_FORMAT_TIFF 4 | |
31 #define RT_FORMAT_IFF 5 | |
32 | |
33 typedef struct SUNRASTContext { | |
34 AVFrame picture; | |
35 } SUNRASTContext; | |
36 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6254
diff
changeset
|
37 static av_cold int sunrast_init(AVCodecContext *avctx) { |
6084 | 38 SUNRASTContext *s = avctx->priv_data; |
39 | |
40 avcodec_get_frame_defaults(&s->picture); | |
41 avctx->coded_frame= &s->picture; | |
42 | |
43 return 0; | |
44 } | |
45 | |
46 static int sunrast_decode_frame(AVCodecContext *avctx, void *data, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8573
diff
changeset
|
47 int *data_size, AVPacket *avpkt) { |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8573
diff
changeset
|
48 const uint8_t *buf = avpkt->data; |
6084 | 49 SUNRASTContext * const s = avctx->priv_data; |
50 AVFrame *picture = data; | |
51 AVFrame * const p = &s->picture; | |
52 unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen; | |
6254 | 53 uint8_t *ptr; |
54 const uint8_t *bufstart = buf; | |
6084 | 55 |
56 if (AV_RB32(buf) != 0x59a66a95) { | |
57 av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n"); | |
58 return -1; | |
59 } | |
60 | |
61 w = AV_RB32(buf+4); | |
62 h = AV_RB32(buf+8); | |
63 depth = AV_RB32(buf+12); | |
64 type = AV_RB32(buf+20); | |
65 maptype = AV_RB32(buf+24); | |
66 maplength = AV_RB32(buf+28); | |
67 | |
10358 | 68 if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) { |
6084 | 69 av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); |
70 return -1; | |
71 } | |
72 if (type > RT_FORMAT_IFF) { | |
73 av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); | |
74 return -1; | |
75 } | |
76 if (maptype & ~1) { | |
77 av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n"); | |
78 return -1; | |
79 } | |
80 | |
81 buf += 32; | |
82 | |
83 switch (depth) { | |
84 case 1: | |
85 avctx->pix_fmt = PIX_FMT_MONOWHITE; | |
86 break; | |
87 case 8: | |
88 avctx->pix_fmt = PIX_FMT_PAL8; | |
89 break; | |
90 case 24: | |
10358 | 91 avctx->pix_fmt = (type == RT_FORMAT_RGB) ? PIX_FMT_RGB24 : PIX_FMT_BGR24; |
6084 | 92 break; |
93 default: | |
94 av_log(avctx, AV_LOG_ERROR, "invalid depth\n"); | |
95 return -1; | |
96 } | |
97 | |
98 if (p->data[0]) | |
99 avctx->release_buffer(avctx, p); | |
100 | |
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12372
diff
changeset
|
101 if (av_image_check_size(w, h, 0, avctx)) |
6084 | 102 return -1; |
103 if (w != avctx->width || h != avctx->height) | |
104 avcodec_set_dimensions(avctx, w, h); | |
105 if (avctx->get_buffer(avctx, p) < 0) { | |
106 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
107 return -1; | |
108 } | |
109 | |
110 p->pict_type = FF_I_TYPE; | |
111 | |
112 if (depth != 8 && maplength) { | |
113 av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n"); | |
114 | |
115 } else if (depth == 8) { | |
116 unsigned int len = maplength / 3; | |
117 | |
118 if (!maplength) { | |
119 av_log(avctx, AV_LOG_ERROR, "colormap expected\n"); | |
120 return -1; | |
121 } | |
122 if (maplength % 3 || maplength > 768) { | |
123 av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); | |
124 return -1; | |
125 } | |
126 | |
127 ptr = p->data[1]; | |
128 for (x=0; x<len; x++, ptr+=4) | |
129 *(uint32_t *)ptr = (buf[x]<<16) + (buf[len+x]<<8) + buf[len+len+x]; | |
130 } | |
131 | |
132 buf += maplength; | |
133 | |
134 ptr = p->data[0]; | |
135 stride = p->linesize[0]; | |
136 | |
137 /* scanlines are aligned on 16 bit boundaries */ | |
138 len = (depth * w + 7) >> 3; | |
139 alen = len + (len&1); | |
140 | |
141 if (type == RT_BYTE_ENCODED) { | |
142 int value, run; | |
143 uint8_t *end = ptr + h*stride; | |
144 | |
145 x = 0; | |
146 while (ptr != end) { | |
147 run = 1; | |
148 if ((value = *buf++) == 0x80) { | |
149 run = *buf++ + 1; | |
150 if (run != 1) | |
151 value = *buf++; | |
152 } | |
153 while (run--) { | |
154 if (x < len) | |
155 ptr[x] = value; | |
156 if (++x >= alen) { | |
157 x = 0; | |
158 ptr += stride; | |
159 if (ptr == end) | |
160 break; | |
161 } | |
162 } | |
163 } | |
164 } else { | |
165 for (y=0; y<h; y++) { | |
166 memcpy(ptr, buf, len); | |
167 ptr += stride; | |
168 buf += alen; | |
169 } | |
170 } | |
171 | |
172 *picture = s->picture; | |
173 *data_size = sizeof(AVFrame); | |
174 | |
175 return buf - bufstart; | |
176 } | |
177 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6254
diff
changeset
|
178 static av_cold int sunrast_end(AVCodecContext *avctx) { |
6084 | 179 SUNRASTContext *s = avctx->priv_data; |
180 | |
181 if(s->picture.data[0]) | |
182 avctx->release_buffer(avctx, &s->picture); | |
183 | |
184 return 0; | |
185 } | |
186 | |
187 AVCodec sunrast_decoder = { | |
188 "sunrast", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10358
diff
changeset
|
189 AVMEDIA_TYPE_VIDEO, |
6084 | 190 CODEC_ID_SUNRAST, |
191 sizeof(SUNRASTContext), | |
192 sunrast_init, | |
193 NULL, | |
194 sunrast_end, | |
195 sunrast_decode_frame, | |
9809
6a3f4053d935
sun rasterfile image decoder uses get_buffer, set CODEC_CAP_DR1
bcoudurier
parents:
9385
diff
changeset
|
196 CODEC_CAP_DR1, |
6722 | 197 NULL, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6722
diff
changeset
|
198 .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), |
6084 | 199 }; |