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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
144 *optr = get_byte(f);
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
165 uint8_t *dest_row;
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
188 /* skip run length table */
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
202 if (expand_rle_row(f, dest_row, z, zsize) != xsize) {
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
203 ret = AVERROR_INVALIDDATA;
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
204 goto fail;
153985f24e5b patch courtesy of Todd Kirby:
melanson
parents: 386
diff changeset
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 };