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