annotate sgi.c @ 386:c152849ee643 libavformat

remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG -> MKTAG/MKBETAG
author melanson
date Sun, 14 Mar 2004 04:04:08 +0000
parents 37a29b5200d8
children 153985f24e5b
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;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
89 uint8_t *dest_row, *tmp_row = NULL;
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 tmp_row = av_malloc(si->xsize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
92
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
93 /* skip header */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
94 url_fseek(f, SGI_HEADER_SIZE, SEEK_SET);
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 pict->linesize[0] = si->xsize;
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 for (z = 0; z < si->zsize; z++) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
99
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
100 #ifndef WORDS_BIGENDIAN
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
101 /* rgba -> bgra for rgba32 on little endian cpus */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
102 if (si->zsize == 4 && z != 3)
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
103 chan_offset = 2 - z;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
104 else
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
105 #endif
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
106 chan_offset = z;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
107
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
108 for (y = si->ysize - 1; y >= 0; y--) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
109 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
110
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
111 if (!get_buffer(f, tmp_row, si->xsize)) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
112 ret = -1;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
113 goto cleanup;
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 for (x = 0; x < si->xsize; x++) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
116 dest_row[chan_offset] = tmp_row[x];
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
117 dest_row += si->zsize;
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 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
121
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
122 cleanup:
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
123 av_free(tmp_row);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
124 return ret;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
125 }
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
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
128 /* expand an rle row into a channel */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
129 static void expand_rle_row(unsigned char *optr, unsigned char *iptr,
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
130 int chan_offset, int pixelstride)
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 unsigned char pixel, count;
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 #ifndef WORDS_BIGENDIAN
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
135 /* rgba -> bgra for rgba32 on little endian cpus */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
136 if (pixelstride == 4 && chan_offset != 3) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
137 chan_offset = 2 - chan_offset;
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 #endif
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
140
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
141 optr += chan_offset;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
142
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
143 while (1) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
144 pixel = *iptr++;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
145
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
146 if (!(count = (pixel & 0x7f))) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
147 return;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
148 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
149 if (pixel & 0x80) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
150 while (count--) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
151 *optr = *iptr;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
152 optr += pixelstride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
153 iptr++;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
154 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
155 } else {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
156 pixel = *iptr++;
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 while (count--) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
159 *optr = pixel;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
160 optr += pixelstride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
161 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
162 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
163 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
164 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
165
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
166
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
167 /* read a run length encoded sgi image */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
168 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
169 AVPicture *pict, ByteIOContext *f)
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 uint8_t *dest_row, *rle_data = NULL;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
172 unsigned long *start_table, *length_table;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
173 int y, z, xsize, ysize, zsize, tablen;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
174 long start_offset, run_length;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
175 int ret = 0;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
176
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
177 xsize = sgi_info->xsize;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
178 ysize = sgi_info->ysize;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
179 zsize = sgi_info->zsize;
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 rle_data = av_malloc(xsize);
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 /* skip header */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
184 url_fseek(f, SGI_HEADER_SIZE, SEEK_SET);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
185
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
186 /* size of rle offset and length tables */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
187 tablen = ysize * zsize * sizeof(long);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
188
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
189 start_table = (unsigned long *)av_malloc(tablen);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
190 length_table = (unsigned long *)av_malloc(tablen);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
191
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
192 if (!get_buffer(f, (uint8_t *)start_table, tablen)) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
193 ret = -1;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
194 goto fail;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
195 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
196
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
197 if (!get_buffer(f, (uint8_t *)length_table, tablen)) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
198 ret = -1;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
199 goto fail;
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
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
202 for (z = 0; z < zsize; z++) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
203 for (y = 0; y < ysize; y++) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
204 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
205
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
206 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
207 run_length = BE_32(&length_table[y + z * ysize]);
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 /* don't seek if already in the correct spot */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
210 if (url_ftell(f) != start_offset) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
211 url_fseek(f, start_offset, SEEK_SET);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
212 }
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 get_buffer(f, rle_data, run_length);
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 expand_rle_row(dest_row, rle_data, z, zsize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
217 }
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
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
220 fail:
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
221 av_free(start_table);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
222 av_free(length_table);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
223 av_free(rle_data);
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 return ret;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
226 }
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 static int sgi_read(ByteIOContext *f,
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
230 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
231 {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
232 SGIInfo sgi_info, *s = &sgi_info;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
233 AVImageInfo info1, *info = &info1;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
234 int ret;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
235
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
236 read_sgi_header(f, s);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
237
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
238 if (s->bytes_per_channel != 1) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
239 return AVERROR_INVALIDDATA;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
240 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
241
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
242 /* check for supported image dimensions */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
243 if (s->dimension != 2 && s->dimension != 3) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
244 return AVERROR_INVALIDDATA;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
245 }
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 if (s->zsize == SGI_GRAYSCALE) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
248 info->pix_fmt = PIX_FMT_GRAY8;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
249 } else if (s->zsize == SGI_RGB) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
250 info->pix_fmt = PIX_FMT_RGB24;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
251 } else if (s->zsize == SGI_RGBA) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
252 info->pix_fmt = PIX_FMT_RGBA32;
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 AVERROR_INVALIDDATA;
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 info->width = s->xsize;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
258 info->height = s->ysize;
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 ret = alloc_cb(opaque, info);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
261 if (ret)
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
262 return ret;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
263
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
264 if (s->rle) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
265 return read_rle_sgi(s, &info->pict, f);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
266 } else {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
267 return read_uncompressed_sgi(s, &info->pict, f);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
268 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
269
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
270 return 0; /* not reached */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
271 }
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 #ifdef CONFIG_ENCODERS
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
274 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
275 {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
276 int i;
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 put_be16(f, SGI_MAGIC);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
279 put_byte(f, info->rle);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
280 put_byte(f, info->bytes_per_channel);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
281 put_be16(f, info->dimension);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
282 put_be16(f, info->xsize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
283 put_be16(f, info->ysize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
284 put_be16(f, info->zsize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
285
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
286 /* The rest are constant in this implementation */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
287 put_be32(f, 0L); /* pixmin */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
288 put_be32(f, 255L); /* pixmax */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
289 put_be32(f, 0L); /* dummy */
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 /* name */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
292 for (i = 0; i < 80; i++) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
293 put_byte(f, 0);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
294 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
295
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
296 put_be32(f, 0L); /* colormap */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
297
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
298 /* 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
299 for (i = 0; i < 404; i++) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
300 put_byte(f, 0);
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 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
303
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
304
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
305 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
306 {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
307 int length, count, i, x;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
308 char *start, repeat = 0;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
309
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
310 for (x = rowsize, length = 0; x > 0;) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
311 start = row;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
312 row += (2 * stride);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
313 x -= 2;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
314
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
315 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
316 row[-1 * stride] != row[0])) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
317 row += stride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
318 x--;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
319 };
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
320
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
321 row -= (2 * stride);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
322 x += 2;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
323
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
324 count = (row - start) / stride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
325 while (count > 0) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
326 i = count > 126 ? 126 : count;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
327 count -= i;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
328
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
329 put_byte(f, 0x80 | i);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
330 length++;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
331
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
332 while (i > 0) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
333 put_byte(f, *start);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
334 start += stride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
335 i--;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
336 length++;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
337 };
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
338 };
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
339
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
340 if (x <= 0) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
341 break;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
342 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
343
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
344 start = row;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
345 repeat = row[0];
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 row += stride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
348 x--;
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 while (x > 0 && *row == repeat) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
351 row += stride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
352 x--;
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 count = (row - start) / stride;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
356 while (count > 0) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
357 i = count > 126 ? 126 : count;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
358 count -= i;
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 put_byte(f, i);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
361 length++;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
362
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
363 put_byte(f, repeat);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
364 length++;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
365 };
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
366 };
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
367
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
368 length++;
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 put_byte(f, 0);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
371 return (length);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
372 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
373
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 static int sgi_write(ByteIOContext *pb, AVImageInfo *info)
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
376 {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
377 SGIInfo sgi_info, *si = &sgi_info;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
378 long *offsettab, *lengthtab;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
379 int i, y, z;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
380 int tablesize, chan_offset;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
381 uint8_t *srcrow;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
382
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
383 si->xsize = info->width;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
384 si->ysize = info->height;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
385 si->rle = 1;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
386 si->bytes_per_channel = 1;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
387
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
388 switch(info->pix_fmt) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
389 case PIX_FMT_GRAY8:
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
390 si->dimension = SGI_SINGLE_CHAN;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
391 si->zsize = SGI_GRAYSCALE;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
392 break;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
393 case PIX_FMT_RGB24:
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
394 si->dimension = SGI_MULTI_CHAN;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
395 si->zsize = SGI_RGB;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
396 break;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
397 case PIX_FMT_RGBA32:
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
398 si->dimension = SGI_MULTI_CHAN;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
399 si->zsize = SGI_RGBA;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
400 break;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
401 default:
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
402 return AVERROR_INVALIDDATA;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
403 }
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 write_sgi_header(pb, si);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
406
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
407 tablesize = si->zsize * si->ysize * sizeof(long);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
408
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
409 /* 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
410 url_fseek(pb, tablesize * 2, SEEK_CUR);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
411 put_flush_packet(pb);
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 lengthtab = av_malloc(tablesize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
414 offsettab = av_malloc(tablesize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
415
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
416 for (z = 0; z < si->zsize; z++) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
417
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
418 #ifndef WORDS_BIGENDIAN
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
419 /* rgba -> bgra for rgba32 on little endian cpus */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
420 if (si->zsize == 4 && z != 3)
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
421 chan_offset = 2 - z;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
422 else
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
423 #endif
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
424 chan_offset = z;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
425
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
426 srcrow = info->pict.data[0] + chan_offset;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
427
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
428 for (y = si->ysize -1; y >= 0; y--) {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
429 offsettab[(z * si->ysize) + y] = url_ftell(pb);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
430 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
431 si->zsize, si->xsize);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
432 srcrow += info->pict.linesize[0];
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
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
436 url_fseek(pb, 512, SEEK_SET);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
437
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
438 /* write offset table */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
439 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
440 put_be32(pb, offsettab[i]);
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
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
443 /* write length table */
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
444 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
445 put_be32(pb, lengthtab[i]);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
446 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
447
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
448 put_flush_packet(pb);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
449
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
450 av_free(lengthtab);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
451 av_free(offsettab);
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
452
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
453 return 0;
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
454 }
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
455 #endif // CONFIG_ENCODERS
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
456
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
457 AVImageFormat sgi_image_format = {
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
458 "sgi",
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
459 "sgi,rgb,rgba,bw",
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
460 sgi_probe,
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
461 sgi_read,
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
462 (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
463 #ifdef CONFIG_ENCODERS
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
464 sgi_write,
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
465 #else
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
466 NULL,
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
467 #endif // CONFIG_ENCODERS
37a29b5200d8 added SGI image format, encoding and decoding, courtesy of Todd Kirby
melanson
parents:
diff changeset
468 };