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; | |
56 | ||
57 | unsigned char *inbuffer; | |
58 | unsigned char *ilbuffer; | |
59 | unsigned char *exbuffer; | |
60 | ||
61 | int inbuflen,ilbuflen,exbuflen; | |
62 | ||
895dbd34 AMH |
63 | io_glue_commit_types(ig); |
64 | mm_log((1, "i_readraw(ig %p,x %d,y %d,datachannels %d,storechannels %d,intrl %d)\n", | |
65 | ig, x, y, datachannels, storechannels, intrl)); | |
02d1d628 | 66 | |
895dbd34 | 67 | im = i_img_empty_ch(NULL,x,y,storechannels); |
50dc291e TC |
68 | if (!im) |
69 | return NULL; | |
02d1d628 | 70 | |
895dbd34 AMH |
71 | inbuflen = im->xsize*datachannels; |
72 | ilbuflen = inbuflen; | |
73 | exbuflen = im->xsize*storechannels; | |
74 | inbuffer = (unsigned char*)mymalloc(inbuflen); | |
02d1d628 AMH |
75 | mm_log((1,"inbuflen: %d, ilbuflen: %d, exbuflen: %d.\n",inbuflen,ilbuflen,exbuflen)); |
76 | ||
5473b91d AMH |
77 | if (intrl==0) ilbuffer = inbuffer; |
78 | else ilbuffer=mymalloc(inbuflen); | |
02d1d628 | 79 | |
5473b91d AMH |
80 | if (datachannels==storechannels) exbuffer=ilbuffer; |
81 | else exbuffer= mymalloc(exbuflen); | |
82 | ||
02d1d628 | 83 | k=0; |
5473b91d | 84 | while( k<im->ysize ) { |
895dbd34 | 85 | rc = ig->readcb(ig, inbuffer, inbuflen); |
5473b91d | 86 | if (rc != inbuflen) { fprintf(stderr,"Premature end of file.\n"); exit(2); } |
02d1d628 AMH |
87 | interleave(inbuffer,ilbuffer,im->xsize,datachannels); |
88 | expandchannels(ilbuffer,exbuffer,im->xsize,datachannels,storechannels); | |
5473b91d | 89 | /* FIXME: Do we ever want to save to a virtual image? */ |
faa9b3e7 | 90 | memcpy(&(im->idata[im->xsize*storechannels*k]),exbuffer,exbuflen); |
02d1d628 AMH |
91 | k++; |
92 | } | |
93 | ||
94 | myfree(inbuffer); | |
5473b91d AMH |
95 | if (intrl != 0) myfree(ilbuffer); |
96 | if (datachannels != storechannels) myfree(exbuffer); | |
50dc291e TC |
97 | |
98 | i_tags_add(&im->tags, "i_format", 0, "raw", -1, 0); | |
99 | ||
02d1d628 AMH |
100 | return im; |
101 | } | |
102 | ||
103 | ||
104 | ||
105 | undef_int | |
895dbd34 | 106 | i_writeraw_wiol(i_img* im, io_glue *ig) { |
02d1d628 | 107 | int rc; |
faa9b3e7 | 108 | |
895dbd34 | 109 | io_glue_commit_types(ig); |
faa9b3e7 | 110 | i_clear_error(); |
895dbd34 | 111 | mm_log((1,"writeraw(im %p,ig %p)\n", im, ig)); |
02d1d628 AMH |
112 | |
113 | if (im == NULL) { mm_log((1,"Image is empty\n")); return(0); } | |
faa9b3e7 | 114 | if (!im->virtual) { |
5473b91d AMH |
115 | rc = ig->writecb(ig,im->idata,im->bytes); |
116 | if (rc != im->bytes) { | |
faa9b3e7 TC |
117 | i_push_error(errno, "Could not write to file"); |
118 | mm_log((1,"i_writeraw: Couldn't write to file\n")); | |
119 | return(0); | |
120 | } | |
5473b91d | 121 | } else { |
faa9b3e7 TC |
122 | if (im->type == i_direct_type) { |
123 | /* just save it as 8-bits, maybe support saving higher bit count | |
124 | raw images later */ | |
125 | int line_size = im->xsize * im->channels; | |
126 | unsigned char *data = mymalloc(line_size); | |
a73aeb5f AMH |
127 | |
128 | int y = 0; | |
129 | rc = line_size; | |
130 | while (rc == line_size && y < im->ysize) { | |
131 | i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels); | |
132 | rc = ig->writecb(ig, data, line_size); | |
133 | ++y; | |
faa9b3e7 TC |
134 | } |
135 | if (rc != line_size) { | |
136 | i_push_error(errno, "write error"); | |
137 | return 0; | |
138 | } | |
a73aeb5f | 139 | myfree(data); |
5473b91d | 140 | } else { |
faa9b3e7 TC |
141 | /* paletted image - assumes the caller puts the palette somewhere |
142 | else | |
143 | */ | |
144 | int line_size = sizeof(i_palidx) * im->xsize; | |
145 | i_palidx *data = mymalloc(sizeof(i_palidx) * im->xsize); | |
a73aeb5f AMH |
146 | |
147 | int y = 0; | |
148 | rc = line_size; | |
149 | while (rc == line_size && y < im->ysize) { | |
150 | i_gpal(im, 0, im->xsize, y, data); | |
151 | rc = ig->writecb(ig, data, line_size); | |
152 | ++y; | |
faa9b3e7 | 153 | } |
a73aeb5f | 154 | myfree(data); |
faa9b3e7 TC |
155 | if (rc != line_size) { |
156 | i_push_error(errno, "write error"); | |
157 | return 0; | |
158 | } | |
159 | } | |
895dbd34 | 160 | } |
10461f9a TC |
161 | |
162 | ig->closecb(ig); | |
163 | ||
02d1d628 AMH |
164 | return(1); |
165 | } |