Commit | Line | Data |
---|---|---|
92bda632 | 1 | #include "imager.h" |
02d1d628 | 2 | #include <stdio.h> |
895dbd34 | 3 | #include "iolayer.h" |
02d1d628 AMH |
4 | #ifndef _MSC_VER |
5 | #include <unistd.h> | |
6 | #endif | |
7 | #include <string.h> | |
faa9b3e7 | 8 | #include <errno.h> |
02d1d628 | 9 | |
895dbd34 | 10 | |
02d1d628 AMH |
11 | |
12 | /* | |
13 | ||
14 | Image loader for raw files. | |
15 | ||
16 | This is a barebones raw loader... | |
17 | ||
18 | fd: filedescriptor | |
19 | x: xsize | |
20 | y: ysize | |
21 | datachannels: the number of channels the file contains | |
22 | storechannels: the bitmap of channels we will read | |
23 | intrl: interlace flag, | |
24 | 0 = sample interleaving | |
25 | 1 = line interleaving | |
26 | 2 = image interleaving | |
27 | ||
28 | */ | |
29 | ||
5473b91d | 30 | static |
02d1d628 | 31 | void |
5473b91d AMH |
32 | interleave(unsigned char *inbuffer,unsigned char *outbuffer,int rowsize,int channels) { |
33 | int ch,ind,i; | |
34 | i=0; | |
35 | if (inbuffer == outbuffer) return; /* Check if data is already in interleaved format */ | |
36 | for (ind=0; ind<rowsize; ind++) | |
37 | for (ch=0; ch<channels; ch++) | |
38 | outbuffer[i++] = inbuffer[rowsize*ch+ind]; | |
39 | } | |
40 | ||
41 | static | |
42 | void | |
43 | expandchannels(unsigned char *inbuffer, unsigned char *outbuffer, | |
44 | int chunks, int datachannels, int storechannels) { | |
02d1d628 | 45 | int ch,i; |
5473b91d AMH |
46 | if (inbuffer == outbuffer) return; /* Check if data is already in expanded format */ |
47 | for(ch=0; ch<chunks; ch++) | |
48 | for (i=0; i<storechannels; i++) | |
49 | outbuffer[ch*storechannels+i] = inbuffer[ch*datachannels+i]; | |
02d1d628 AMH |
50 | } |
51 | ||
52 | i_img * | |
895dbd34 | 53 | i_readraw_wiol(io_glue *ig, int x, int y, int datachannels, int storechannels, int intrl) { |
02d1d628 AMH |
54 | i_img* im; |
55 | int rc,k; | |
5f8f8e17 | 56 | |
02d1d628 AMH |
57 | unsigned char *inbuffer; |
58 | unsigned char *ilbuffer; | |
59 | unsigned char *exbuffer; | |
60 | ||
61 | int inbuflen,ilbuflen,exbuflen; | |
62 | ||
885e13c5 TC |
63 | i_clear_error(); |
64 | ||
895dbd34 AMH |
65 | io_glue_commit_types(ig); |
66 | mm_log((1, "i_readraw(ig %p,x %d,y %d,datachannels %d,storechannels %d,intrl %d)\n", | |
67 | ig, x, y, datachannels, storechannels, intrl)); | |
02d1d628 | 68 | |
895dbd34 | 69 | im = i_img_empty_ch(NULL,x,y,storechannels); |
50dc291e TC |
70 | if (!im) |
71 | return NULL; | |
02d1d628 | 72 | |
895dbd34 AMH |
73 | inbuflen = im->xsize*datachannels; |
74 | ilbuflen = inbuflen; | |
75 | exbuflen = im->xsize*storechannels; | |
76 | inbuffer = (unsigned char*)mymalloc(inbuflen); | |
02d1d628 AMH |
77 | mm_log((1,"inbuflen: %d, ilbuflen: %d, exbuflen: %d.\n",inbuflen,ilbuflen,exbuflen)); |
78 | ||
5473b91d AMH |
79 | if (intrl==0) ilbuffer = inbuffer; |
80 | else ilbuffer=mymalloc(inbuflen); | |
02d1d628 | 81 | |
5473b91d AMH |
82 | if (datachannels==storechannels) exbuffer=ilbuffer; |
83 | else exbuffer= mymalloc(exbuflen); | |
84 | ||
02d1d628 | 85 | k=0; |
5473b91d | 86 | while( k<im->ysize ) { |
895dbd34 | 87 | rc = ig->readcb(ig, inbuffer, inbuflen); |
5f8f8e17 TC |
88 | if (rc != inbuflen) { |
89 | if (rc < 0) | |
90 | i_push_error(0, "error reading file"); | |
91 | else | |
92 | i_push_error(0, "premature end of file"); | |
93 | i_img_destroy(im); | |
94 | myfree(inbuffer); | |
95 | if (intrl != 0) myfree(ilbuffer); | |
96 | if (datachannels != storechannels) myfree(exbuffer); | |
97 | return NULL; | |
98 | } | |
02d1d628 AMH |
99 | interleave(inbuffer,ilbuffer,im->xsize,datachannels); |
100 | expandchannels(ilbuffer,exbuffer,im->xsize,datachannels,storechannels); | |
5473b91d | 101 | /* FIXME: Do we ever want to save to a virtual image? */ |
faa9b3e7 | 102 | memcpy(&(im->idata[im->xsize*storechannels*k]),exbuffer,exbuflen); |
02d1d628 AMH |
103 | k++; |
104 | } | |
105 | ||
106 | myfree(inbuffer); | |
5473b91d AMH |
107 | if (intrl != 0) myfree(ilbuffer); |
108 | if (datachannels != storechannels) myfree(exbuffer); | |
50dc291e TC |
109 | |
110 | i_tags_add(&im->tags, "i_format", 0, "raw", -1, 0); | |
111 | ||
02d1d628 AMH |
112 | return im; |
113 | } | |
114 | ||
115 | ||
116 | ||
117 | undef_int | |
895dbd34 | 118 | i_writeraw_wiol(i_img* im, io_glue *ig) { |
02d1d628 | 119 | int rc; |
faa9b3e7 | 120 | |
895dbd34 | 121 | io_glue_commit_types(ig); |
faa9b3e7 | 122 | i_clear_error(); |
895dbd34 | 123 | mm_log((1,"writeraw(im %p,ig %p)\n", im, ig)); |
02d1d628 AMH |
124 | |
125 | if (im == NULL) { mm_log((1,"Image is empty\n")); return(0); } | |
faa9b3e7 | 126 | if (!im->virtual) { |
5473b91d AMH |
127 | rc = ig->writecb(ig,im->idata,im->bytes); |
128 | if (rc != im->bytes) { | |
faa9b3e7 TC |
129 | i_push_error(errno, "Could not write to file"); |
130 | mm_log((1,"i_writeraw: Couldn't write to file\n")); | |
131 | return(0); | |
132 | } | |
5473b91d | 133 | } else { |
faa9b3e7 TC |
134 | if (im->type == i_direct_type) { |
135 | /* just save it as 8-bits, maybe support saving higher bit count | |
136 | raw images later */ | |
137 | int line_size = im->xsize * im->channels; | |
138 | unsigned char *data = mymalloc(line_size); | |
a73aeb5f AMH |
139 | |
140 | int y = 0; | |
141 | rc = line_size; | |
142 | while (rc == line_size && y < im->ysize) { | |
143 | i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels); | |
144 | rc = ig->writecb(ig, data, line_size); | |
145 | ++y; | |
faa9b3e7 TC |
146 | } |
147 | if (rc != line_size) { | |
148 | i_push_error(errno, "write error"); | |
149 | return 0; | |
150 | } | |
a73aeb5f | 151 | myfree(data); |
5473b91d | 152 | } else { |
faa9b3e7 TC |
153 | /* paletted image - assumes the caller puts the palette somewhere |
154 | else | |
155 | */ | |
156 | int line_size = sizeof(i_palidx) * im->xsize; | |
157 | i_palidx *data = mymalloc(sizeof(i_palidx) * im->xsize); | |
a73aeb5f AMH |
158 | |
159 | int y = 0; | |
160 | rc = line_size; | |
161 | while (rc == line_size && y < im->ysize) { | |
162 | i_gpal(im, 0, im->xsize, y, data); | |
163 | rc = ig->writecb(ig, data, line_size); | |
164 | ++y; | |
faa9b3e7 | 165 | } |
a73aeb5f | 166 | myfree(data); |
faa9b3e7 TC |
167 | if (rc != line_size) { |
168 | i_push_error(errno, "write error"); | |
169 | return 0; | |
170 | } | |
171 | } | |
895dbd34 | 172 | } |
10461f9a TC |
173 | |
174 | ig->closecb(ig); | |
175 | ||
02d1d628 AMH |
176 | return(1); |
177 | } |