Mercurial > libavformat.hg
annotate sgi.c @ 584:4e3bab6555ae libavformat
When playing
ftp://ftp.mplayerhq.hu/MPlayer/samples/V-codecs/QPEG/VWbig6.avi with my
decoder (should appear soon) it hadn't changed palette even there are
palette change chunks in that AVI.
Here is small patch to make it work (zero number of colors to change in
that chunk actually means to change ALL colors).
patch by (Kostya <cannonball>at<bw-team>dot<com>)
author | michael |
---|---|
date | Fri, 12 Nov 2004 01:32:35 +0000 |
parents | 153985f24e5b |
children | 0b52743104ac |
rev | line source |
---|---|
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
1 /* |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
2 * SGI image format |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
3 * Todd Kirby <doubleshot@pacbell.net> |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
4 * |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
5 * This library is free software; you can redistribute it and/or |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
6 * modify it under the terms of the GNU Lesser General Public |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
7 * License as published by the Free Software Foundation; either |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
8 * version 2 of the License, or (at your option) any later version. |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
9 * |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
10 * This library is distributed in the hope that it will be useful, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
13 * Lesser General Public License for more details. |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
14 * |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
15 * You should have received a copy of the GNU Lesser General Public |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
16 * License along with this library; if not, write to the Free Software |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
18 */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
19 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
20 #include "avformat.h" |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
21 #include "avio.h" |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
22 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
23 /* #define DEBUG */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
24 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
25 /* sgi image file signature */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
26 #define SGI_MAGIC 474 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
27 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
28 #define SGI_HEADER_SIZE 512 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
29 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
30 #define SGI_GRAYSCALE 1 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
31 #define SGI_RGB 3 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
32 #define SGI_RGBA 4 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
33 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
34 #define SGI_SINGLE_CHAN 2 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
35 #define SGI_MULTI_CHAN 3 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
36 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
37 typedef struct SGIInfo{ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
38 short magic; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
39 char rle; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
40 char bytes_per_channel; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
41 unsigned short dimension; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
42 unsigned short xsize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
43 unsigned short ysize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
44 unsigned short zsize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
45 } SGIInfo; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
46 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
47 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
48 static int sgi_probe(AVProbeData *pd) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
49 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
50 /* test for sgi magic */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
51 if (pd->buf_size >= 2 && BE_16(&pd->buf[0]) == SGI_MAGIC) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
52 return AVPROBE_SCORE_MAX; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
53 } else { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
54 return 0; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
55 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
56 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
57 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
58 /* read sgi header fields */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
59 static void read_sgi_header(ByteIOContext *f, SGIInfo *info) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
60 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
61 info->magic = (unsigned short) get_be16(f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
62 info->rle = get_byte(f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
63 info->bytes_per_channel = get_byte(f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
64 info->dimension = (unsigned short)get_be16(f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
65 info->xsize = (unsigned short) get_be16(f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
66 info->ysize = (unsigned short) get_be16(f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
67 info->zsize = (unsigned short) get_be16(f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
68 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
69 #ifdef DEBUG |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
70 printf("sgi header fields:\n"); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
71 printf(" magic: %d\n", info->magic); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
72 printf(" rle: %d\n", info->rle); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
73 printf(" bpc: %d\n", info->bytes_per_channel); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
74 printf(" dim: %d\n", info->dimension); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
75 printf(" xsize: %d\n", info->xsize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
76 printf(" ysize: %d\n", info->ysize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
77 printf(" zsize: %d\n", info->zsize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
78 #endif |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
79 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
80 return; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
81 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
82 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
83 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
84 /* read an uncompressed sgi image */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
85 static int read_uncompressed_sgi(const SGIInfo *si, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
86 AVPicture *pict, ByteIOContext *f) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
87 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
88 int x, y, z, chan_offset, ret = 0; |
430 | 89 uint8_t *dest_row; |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
90 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
91 /* skip header */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
92 url_fseek(f, SGI_HEADER_SIZE, SEEK_SET); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
93 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
94 pict->linesize[0] = si->xsize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
95 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
96 for (z = 0; z < si->zsize; z++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
97 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
98 #ifndef WORDS_BIGENDIAN |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
99 /* rgba -> bgra for rgba32 on little endian cpus */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
100 if (si->zsize == 4 && z != 3) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
101 chan_offset = 2 - z; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
102 else |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
103 #endif |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
104 chan_offset = z; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
105 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
106 for (y = si->ysize - 1; y >= 0; y--) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
107 dest_row = pict->data[0] + (y * si->xsize * si->zsize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
108 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
109 for (x = 0; x < si->xsize; x++) { |
430 | 110 dest_row[chan_offset] = get_byte(f); |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
111 dest_row += si->zsize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
112 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
113 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
114 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
115 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
116 return ret; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
117 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
118 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
119 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
120 /* expand an rle row into a channel */ |
430 | 121 static int expand_rle_row(ByteIOContext *f, unsigned char *optr, |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
122 int chan_offset, int pixelstride) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
123 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
124 unsigned char pixel, count; |
430 | 125 int length = 0; |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
126 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
127 #ifndef WORDS_BIGENDIAN |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
128 /* rgba -> bgra for rgba32 on little endian cpus */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
129 if (pixelstride == 4 && chan_offset != 3) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
130 chan_offset = 2 - chan_offset; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
131 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
132 #endif |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
133 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
134 optr += chan_offset; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
135 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
136 while (1) { |
430 | 137 pixel = get_byte(f); |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
138 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
139 if (!(count = (pixel & 0x7f))) { |
430 | 140 return length; |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
141 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
142 if (pixel & 0x80) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
143 while (count--) { |
430 | 144 *optr = get_byte(f); |
145 length++; | |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
146 optr += pixelstride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
147 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
148 } else { |
430 | 149 pixel = get_byte(f); |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
150 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
151 while (count--) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
152 *optr = pixel; |
430 | 153 length++; |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
154 optr += pixelstride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
155 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
156 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
157 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
158 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
159 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
160 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
161 /* read a run length encoded sgi image */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
162 static int read_rle_sgi(const SGIInfo *sgi_info, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
163 AVPicture *pict, ByteIOContext *f) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
164 { |
430 | 165 uint8_t *dest_row; |
166 unsigned long *start_table; | |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
167 int y, z, xsize, ysize, zsize, tablen; |
430 | 168 long start_offset; |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
169 int ret = 0; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
170 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
171 xsize = sgi_info->xsize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
172 ysize = sgi_info->ysize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
173 zsize = sgi_info->zsize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
174 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
175 /* skip header */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
176 url_fseek(f, SGI_HEADER_SIZE, SEEK_SET); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
177 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
178 /* size of rle offset and length tables */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
179 tablen = ysize * zsize * sizeof(long); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
180 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
181 start_table = (unsigned long *)av_malloc(tablen); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
182 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
183 if (!get_buffer(f, (uint8_t *)start_table, tablen)) { |
430 | 184 ret = AVERROR_IO; |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
185 goto fail; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
186 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
187 |
430 | 188 /* skip run length table */ |
189 url_fseek(f, tablen, SEEK_CUR); | |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
190 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
191 for (z = 0; z < zsize; z++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
192 for (y = 0; y < ysize; y++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
193 dest_row = pict->data[0] + (ysize - 1 - y) * (xsize * zsize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
194 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
195 start_offset = BE_32(&start_table[y + z * ysize]); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
196 |
430 | 197 /* don't seek if already at the next rle start offset */ |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
198 if (url_ftell(f) != start_offset) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
199 url_fseek(f, start_offset, SEEK_SET); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
200 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
201 |
430 | 202 if (expand_rle_row(f, dest_row, z, zsize) != xsize) { |
203 ret = AVERROR_INVALIDDATA; | |
204 goto fail; | |
205 } | |
382
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
206 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
207 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
208 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
209 fail: |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
210 av_free(start_table); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
211 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
212 return ret; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
213 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
214 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
215 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
216 static int sgi_read(ByteIOContext *f, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
217 int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
218 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
219 SGIInfo sgi_info, *s = &sgi_info; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
220 AVImageInfo info1, *info = &info1; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
221 int ret; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
222 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
223 read_sgi_header(f, s); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
224 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
225 if (s->bytes_per_channel != 1) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
226 return AVERROR_INVALIDDATA; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
227 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
228 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
229 /* check for supported image dimensions */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
230 if (s->dimension != 2 && s->dimension != 3) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
231 return AVERROR_INVALIDDATA; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
232 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
233 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
234 if (s->zsize == SGI_GRAYSCALE) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
235 info->pix_fmt = PIX_FMT_GRAY8; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
236 } else if (s->zsize == SGI_RGB) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
237 info->pix_fmt = PIX_FMT_RGB24; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
238 } else if (s->zsize == SGI_RGBA) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
239 info->pix_fmt = PIX_FMT_RGBA32; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
240 } else { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
241 return AVERROR_INVALIDDATA; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
242 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
243 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
244 info->width = s->xsize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
245 info->height = s->ysize; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
246 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
247 ret = alloc_cb(opaque, info); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
248 if (ret) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
249 return ret; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
250 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
251 if (s->rle) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
252 return read_rle_sgi(s, &info->pict, f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
253 } else { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
254 return read_uncompressed_sgi(s, &info->pict, f); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
255 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
256 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
257 return 0; /* not reached */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
258 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
259 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
260 #ifdef CONFIG_ENCODERS |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
261 static void write_sgi_header(ByteIOContext *f, const SGIInfo *info) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
262 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
263 int i; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
264 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
265 put_be16(f, SGI_MAGIC); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
266 put_byte(f, info->rle); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
267 put_byte(f, info->bytes_per_channel); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
268 put_be16(f, info->dimension); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
269 put_be16(f, info->xsize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
270 put_be16(f, info->ysize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
271 put_be16(f, info->zsize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
272 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
273 /* The rest are constant in this implementation */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
274 put_be32(f, 0L); /* pixmin */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
275 put_be32(f, 255L); /* pixmax */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
276 put_be32(f, 0L); /* dummy */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
277 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
278 /* name */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
279 for (i = 0; i < 80; i++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
280 put_byte(f, 0); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
281 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
282 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
283 put_be32(f, 0L); /* colormap */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
284 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
285 /* The rest of the 512 byte header is unused. */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
286 for (i = 0; i < 404; i++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
287 put_byte(f, 0); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
288 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
289 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
290 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
291 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
292 static int rle_row(ByteIOContext *f, char *row, int stride, int rowsize) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
293 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
294 int length, count, i, x; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
295 char *start, repeat = 0; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
296 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
297 for (x = rowsize, length = 0; x > 0;) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
298 start = row; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
299 row += (2 * stride); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
300 x -= 2; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
301 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
302 while (x > 0 && (row[-2 * stride] != row[-1 * stride] || |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
303 row[-1 * stride] != row[0])) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
304 row += stride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
305 x--; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
306 }; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
307 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
308 row -= (2 * stride); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
309 x += 2; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
310 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
311 count = (row - start) / stride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
312 while (count > 0) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
313 i = count > 126 ? 126 : count; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
314 count -= i; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
315 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
316 put_byte(f, 0x80 | i); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
317 length++; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
318 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
319 while (i > 0) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
320 put_byte(f, *start); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
321 start += stride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
322 i--; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
323 length++; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
324 }; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
325 }; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
326 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
327 if (x <= 0) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
328 break; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
329 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
330 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
331 start = row; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
332 repeat = row[0]; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
333 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
334 row += stride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
335 x--; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
336 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
337 while (x > 0 && *row == repeat) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
338 row += stride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
339 x--; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
340 }; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
341 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
342 count = (row - start) / stride; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
343 while (count > 0) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
344 i = count > 126 ? 126 : count; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
345 count -= i; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
346 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
347 put_byte(f, i); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
348 length++; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
349 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
350 put_byte(f, repeat); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
351 length++; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
352 }; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
353 }; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
354 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
355 length++; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
356 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
357 put_byte(f, 0); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
358 return (length); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
359 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
360 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
361 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
362 static int sgi_write(ByteIOContext *pb, AVImageInfo *info) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
363 { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
364 SGIInfo sgi_info, *si = &sgi_info; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
365 long *offsettab, *lengthtab; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
366 int i, y, z; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
367 int tablesize, chan_offset; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
368 uint8_t *srcrow; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
369 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
370 si->xsize = info->width; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
371 si->ysize = info->height; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
372 si->rle = 1; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
373 si->bytes_per_channel = 1; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
374 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
375 switch(info->pix_fmt) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
376 case PIX_FMT_GRAY8: |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
377 si->dimension = SGI_SINGLE_CHAN; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
378 si->zsize = SGI_GRAYSCALE; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
379 break; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
380 case PIX_FMT_RGB24: |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
381 si->dimension = SGI_MULTI_CHAN; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
382 si->zsize = SGI_RGB; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
383 break; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
384 case PIX_FMT_RGBA32: |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
385 si->dimension = SGI_MULTI_CHAN; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
386 si->zsize = SGI_RGBA; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
387 break; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
388 default: |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
389 return AVERROR_INVALIDDATA; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
390 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
391 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
392 write_sgi_header(pb, si); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
393 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
394 tablesize = si->zsize * si->ysize * sizeof(long); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
395 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
396 /* skip rle offset and length tables, write them at the end. */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
397 url_fseek(pb, tablesize * 2, SEEK_CUR); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
398 put_flush_packet(pb); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
399 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
400 lengthtab = av_malloc(tablesize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
401 offsettab = av_malloc(tablesize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
402 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
403 for (z = 0; z < si->zsize; z++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
404 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
405 #ifndef WORDS_BIGENDIAN |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
406 /* rgba -> bgra for rgba32 on little endian cpus */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
407 if (si->zsize == 4 && z != 3) |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
408 chan_offset = 2 - z; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
409 else |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
410 #endif |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
411 chan_offset = z; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
412 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
413 srcrow = info->pict.data[0] + chan_offset; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
414 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
415 for (y = si->ysize -1; y >= 0; y--) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
416 offsettab[(z * si->ysize) + y] = url_ftell(pb); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
417 lengthtab[(z * si->ysize) + y] = rle_row(pb, srcrow, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
418 si->zsize, si->xsize); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
419 srcrow += info->pict.linesize[0]; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
420 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
421 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
422 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
423 url_fseek(pb, 512, SEEK_SET); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
424 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
425 /* write offset table */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
426 for (i = 0; i < (si->ysize * si->zsize); i++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
427 put_be32(pb, offsettab[i]); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
428 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
429 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
430 /* write length table */ |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
431 for (i = 0; i < (si->ysize * si->zsize); i++) { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
432 put_be32(pb, lengthtab[i]); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
433 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
434 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
435 put_flush_packet(pb); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
436 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
437 av_free(lengthtab); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
438 av_free(offsettab); |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
439 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
440 return 0; |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
441 } |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
442 #endif // CONFIG_ENCODERS |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
443 |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
444 AVImageFormat sgi_image_format = { |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
445 "sgi", |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
446 "sgi,rgb,rgba,bw", |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
447 sgi_probe, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
448 sgi_read, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
449 (1 << PIX_FMT_GRAY8) | (1 << PIX_FMT_RGB24) | (1 << PIX_FMT_RGBA32), |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
450 #ifdef CONFIG_ENCODERS |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
451 sgi_write, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
452 #else |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
453 NULL, |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
454 #endif // CONFIG_ENCODERS |
37a29b5200d8
added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff
changeset
|
455 }; |