Blame


1 28994509 2004-04-21 devnull #include <u.h>
2 28994509 2004-04-21 devnull #include <libc.h>
3 28994509 2004-04-21 devnull #include <bio.h>
4 28994509 2004-04-21 devnull #include <draw.h>
5 28994509 2004-04-21 devnull #include "imagefile.h"
6 28994509 2004-04-21 devnull
7 28994509 2004-04-21 devnull /*
8 28994509 2004-04-21 devnull * Hacked version for writing from Rawimage to file.
9 28994509 2004-04-21 devnull * Assumes 8 bits per component.
10 28994509 2004-04-21 devnull */
11 28994509 2004-04-21 devnull
12 28994509 2004-04-21 devnull #define HSHIFT 3 /* HSHIFT==5 runs slightly faster, but hash table is 64x bigger */
13 28994509 2004-04-21 devnull #define NHASH (1<<(HSHIFT*NMATCH))
14 28994509 2004-04-21 devnull #define HMASK (NHASH-1)
15 28994509 2004-04-21 devnull #define hupdate(h, c) ((((h)<<HSHIFT)^(c))&HMASK)
16 28994509 2004-04-21 devnull typedef struct Hlist Hlist;
17 28994509 2004-04-21 devnull struct Hlist{
18 28994509 2004-04-21 devnull uchar *s;
19 28994509 2004-04-21 devnull Hlist *next, *prev;
20 28994509 2004-04-21 devnull };
21 28994509 2004-04-21 devnull
22 28994509 2004-04-21 devnull int
23 28994509 2004-04-21 devnull writerawimage(int fd, Rawimage *i)
24 28994509 2004-04-21 devnull {
25 28994509 2004-04-21 devnull uchar *outbuf, *outp, *eout; /* encoded data, pointer, end */
26 28994509 2004-04-21 devnull uchar *loutp; /* start of encoded line */
27 28994509 2004-04-21 devnull Hlist *hash; /* heads of hash chains of past strings */
28 28994509 2004-04-21 devnull Hlist *chain, *hp; /* hash chain members, pointer */
29 28994509 2004-04-21 devnull Hlist *cp; /* next Hlist to fall out of window */
30 28994509 2004-04-21 devnull int h; /* hash value */
31 28994509 2004-04-21 devnull uchar *line, *eline; /* input line, end pointer */
32 28994509 2004-04-21 devnull uchar *data, *edata; /* input buffer, end pointer */
33 28994509 2004-04-21 devnull ulong n; /* length of input buffer */
34 28994509 2004-04-21 devnull int bpl; /* input line length */
35 28994509 2004-04-21 devnull int offs, runlen; /* offset, length of consumed data */
36 28994509 2004-04-21 devnull uchar dumpbuf[NDUMP]; /* dump accumulator */
37 28994509 2004-04-21 devnull int ndump; /* length of dump accumulator */
38 28994509 2004-04-21 devnull int ncblock; /* size of buffer */
39 28994509 2004-04-21 devnull Rectangle r;
40 28994509 2004-04-21 devnull uchar *p, *q, *s, *es, *t;
41 28994509 2004-04-21 devnull char hdr[11+5*12+1], buf[16];
42 28994509 2004-04-21 devnull ulong desc;
43 28994509 2004-04-21 devnull
44 28994509 2004-04-21 devnull r = i->r;
45 28994509 2004-04-21 devnull switch(i->chandesc){
46 28994509 2004-04-21 devnull default:
47 28994509 2004-04-21 devnull werrstr("can't handle chandesc %d", i->chandesc);
48 28994509 2004-04-21 devnull return -1;
49 28994509 2004-04-21 devnull case CY:
50 28994509 2004-04-21 devnull bpl = Dx(r);
51 28994509 2004-04-21 devnull desc = GREY8;
52 28994509 2004-04-21 devnull break;
53 28994509 2004-04-21 devnull case CYA16:
54 28994509 2004-04-21 devnull bpl = 2*Dx(r);
55 28994509 2004-04-21 devnull desc = CHAN2(CGrey, 8, CAlpha, 8);
56 28994509 2004-04-21 devnull break;
57 28994509 2004-04-21 devnull case CRGBV:
58 28994509 2004-04-21 devnull bpl = Dx(r);
59 28994509 2004-04-21 devnull desc = CMAP8;
60 28994509 2004-04-21 devnull break;
61 28994509 2004-04-21 devnull case CRGBVA16:
62 28994509 2004-04-21 devnull bpl = 2*Dx(r);
63 28994509 2004-04-21 devnull desc = CHAN2(CMap, 8, CAlpha, 8);
64 28994509 2004-04-21 devnull break;
65 28994509 2004-04-21 devnull case CRGB24:
66 28994509 2004-04-21 devnull bpl = 3*Dx(r);
67 28994509 2004-04-21 devnull desc = RGB24;
68 28994509 2004-04-21 devnull break;
69 28994509 2004-04-21 devnull case CRGBA32:
70 28994509 2004-04-21 devnull bpl = 4*Dx(r);
71 28994509 2004-04-21 devnull desc = RGBA32;
72 28994509 2004-04-21 devnull break;
73 28994509 2004-04-21 devnull }
74 28994509 2004-04-21 devnull ncblock = _compblocksize(r, bpl/Dx(r));
75 28994509 2004-04-21 devnull outbuf = malloc(ncblock);
76 28994509 2004-04-21 devnull hash = malloc(NHASH*sizeof(Hlist));
77 28994509 2004-04-21 devnull chain = malloc(NMEM*sizeof(Hlist));
78 28994509 2004-04-21 devnull if(outbuf == 0 || hash == 0 || chain == 0){
79 28994509 2004-04-21 devnull ErrOut:
80 28994509 2004-04-21 devnull free(outbuf);
81 28994509 2004-04-21 devnull free(hash);
82 28994509 2004-04-21 devnull free(chain);
83 28994509 2004-04-21 devnull return -1;
84 28994509 2004-04-21 devnull }
85 28994509 2004-04-21 devnull n = Dy(r)*bpl;
86 28994509 2004-04-21 devnull data = i->chans[0];
87 28994509 2004-04-21 devnull sprint(hdr, "compressed\n%11s %11d %11d %11d %11d ",
88 28994509 2004-04-21 devnull chantostr(buf, desc), r.min.x, r.min.y, r.max.x, r.max.y);
89 28994509 2004-04-21 devnull if(write(fd, hdr, 11+5*12) != 11+5*12){
90 28994509 2004-04-21 devnull werrstr("i/o error writing header");
91 28994509 2004-04-21 devnull goto ErrOut;
92 28994509 2004-04-21 devnull }
93 28994509 2004-04-21 devnull edata = data+n;
94 28994509 2004-04-21 devnull eout = outbuf+ncblock;
95 28994509 2004-04-21 devnull line = data;
96 28994509 2004-04-21 devnull r.max.y = r.min.y;
97 28994509 2004-04-21 devnull while(line != edata){
98 28994509 2004-04-21 devnull memset(hash, 0, NHASH*sizeof(Hlist));
99 28994509 2004-04-21 devnull memset(chain, 0, NMEM*sizeof(Hlist));
100 28994509 2004-04-21 devnull cp = chain;
101 28994509 2004-04-21 devnull h = 0;
102 28994509 2004-04-21 devnull outp = outbuf;
103 28994509 2004-04-21 devnull for(n = 0; n != NMATCH; n++)
104 28994509 2004-04-21 devnull h = hupdate(h, line[n]);
105 28994509 2004-04-21 devnull loutp = outbuf;
106 28994509 2004-04-21 devnull while(line != edata){
107 28994509 2004-04-21 devnull ndump = 0;
108 28994509 2004-04-21 devnull eline = line+bpl;
109 28994509 2004-04-21 devnull for(p = line; p != eline; ){
110 28994509 2004-04-21 devnull if(eline-p < NRUN)
111 28994509 2004-04-21 devnull es = eline;
112 28994509 2004-04-21 devnull else
113 28994509 2004-04-21 devnull es = p+NRUN;
114 28994509 2004-04-21 devnull q = 0;
115 28994509 2004-04-21 devnull runlen = 0;
116 28994509 2004-04-21 devnull for(hp = hash[h].next; hp; hp = hp->next){
117 28994509 2004-04-21 devnull s = p + runlen;
118 28994509 2004-04-21 devnull if(s >= es)
119 28994509 2004-04-21 devnull continue;
120 28994509 2004-04-21 devnull t = hp->s + runlen;
121 28994509 2004-04-21 devnull for(; s >= p; s--)
122 28994509 2004-04-21 devnull if(*s != *t--)
123 28994509 2004-04-21 devnull goto matchloop;
124 28994509 2004-04-21 devnull t += runlen+2;
125 28994509 2004-04-21 devnull s += runlen+2;
126 28994509 2004-04-21 devnull for(; s < es; s++)
127 28994509 2004-04-21 devnull if(*s != *t++)
128 28994509 2004-04-21 devnull break;
129 28994509 2004-04-21 devnull n = s-p;
130 28994509 2004-04-21 devnull if(n > runlen){
131 28994509 2004-04-21 devnull runlen = n;
132 28994509 2004-04-21 devnull q = hp->s;
133 28994509 2004-04-21 devnull if(n == NRUN)
134 28994509 2004-04-21 devnull break;
135 28994509 2004-04-21 devnull }
136 28994509 2004-04-21 devnull matchloop: ;
137 28994509 2004-04-21 devnull }
138 28994509 2004-04-21 devnull if(runlen < NMATCH){
139 28994509 2004-04-21 devnull if(ndump == NDUMP){
140 28994509 2004-04-21 devnull if(eout-outp < ndump+1)
141 28994509 2004-04-21 devnull goto Bfull;
142 28994509 2004-04-21 devnull *outp++ = ndump-1+128;
143 28994509 2004-04-21 devnull memmove(outp, dumpbuf, ndump);
144 28994509 2004-04-21 devnull outp += ndump;
145 28994509 2004-04-21 devnull ndump = 0;
146 28994509 2004-04-21 devnull }
147 28994509 2004-04-21 devnull dumpbuf[ndump++] = *p;
148 28994509 2004-04-21 devnull runlen = 1;
149 28994509 2004-04-21 devnull }
150 28994509 2004-04-21 devnull else{
151 28994509 2004-04-21 devnull if(ndump != 0){
152 28994509 2004-04-21 devnull if(eout-outp < ndump+1)
153 28994509 2004-04-21 devnull goto Bfull;
154 28994509 2004-04-21 devnull *outp++ = ndump-1+128;
155 28994509 2004-04-21 devnull memmove(outp, dumpbuf, ndump);
156 28994509 2004-04-21 devnull outp += ndump;
157 28994509 2004-04-21 devnull ndump = 0;
158 28994509 2004-04-21 devnull }
159 28994509 2004-04-21 devnull offs = p-q-1;
160 28994509 2004-04-21 devnull if(eout-outp < 2)
161 28994509 2004-04-21 devnull goto Bfull;
162 28994509 2004-04-21 devnull *outp++ = ((runlen-NMATCH)<<2) + (offs>>8);
163 28994509 2004-04-21 devnull *outp++ = offs&255;
164 28994509 2004-04-21 devnull }
165 28994509 2004-04-21 devnull for(q = p+runlen; p != q; p++){
166 28994509 2004-04-21 devnull if(cp->prev)
167 28994509 2004-04-21 devnull cp->prev->next = 0;
168 28994509 2004-04-21 devnull cp->next = hash[h].next;
169 28994509 2004-04-21 devnull cp->prev = &hash[h];
170 28994509 2004-04-21 devnull if(cp->next)
171 28994509 2004-04-21 devnull cp->next->prev = cp;
172 28994509 2004-04-21 devnull cp->prev->next = cp;
173 28994509 2004-04-21 devnull cp->s = p;
174 28994509 2004-04-21 devnull if(++cp == &chain[NMEM])
175 28994509 2004-04-21 devnull cp = chain;
176 28994509 2004-04-21 devnull if(edata-p > NMATCH)
177 28994509 2004-04-21 devnull h = hupdate(h, p[NMATCH]);
178 28994509 2004-04-21 devnull }
179 28994509 2004-04-21 devnull }
180 28994509 2004-04-21 devnull if(ndump != 0){
181 28994509 2004-04-21 devnull if(eout-outp < ndump+1)
182 28994509 2004-04-21 devnull goto Bfull;
183 28994509 2004-04-21 devnull *outp++ = ndump-1+128;
184 28994509 2004-04-21 devnull memmove(outp, dumpbuf, ndump);
185 28994509 2004-04-21 devnull outp += ndump;
186 28994509 2004-04-21 devnull }
187 28994509 2004-04-21 devnull line = eline;
188 28994509 2004-04-21 devnull loutp = outp;
189 28994509 2004-04-21 devnull r.max.y++;
190 28994509 2004-04-21 devnull }
191 28994509 2004-04-21 devnull Bfull:
192 28994509 2004-04-21 devnull if(loutp == outbuf){
193 28994509 2004-04-21 devnull werrstr("compressor out of sync");
194 28994509 2004-04-21 devnull goto ErrOut;
195 28994509 2004-04-21 devnull }
196 28994509 2004-04-21 devnull n = loutp-outbuf;
197 28994509 2004-04-21 devnull sprint(hdr, "%11d %11ld ", r.max.y, n);
198 28994509 2004-04-21 devnull write(fd, hdr, 2*12);
199 28994509 2004-04-21 devnull write(fd, outbuf, n);
200 28994509 2004-04-21 devnull r.min.y = r.max.y;
201 28994509 2004-04-21 devnull }
202 28994509 2004-04-21 devnull free(outbuf);
203 28994509 2004-04-21 devnull free(hash);
204 28994509 2004-04-21 devnull free(chain);
205 28994509 2004-04-21 devnull return 0;
206 28994509 2004-04-21 devnull }