readgif.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. #include <u.h>
  2. #include <lib9.h>
  3. #include <bio.h>
  4. #include <draw.h>
  5. #include "imagefile.h"
  6. typedef struct Entry Entry;
  7. typedef struct Header Header;
  8. struct Entry{
  9. int prefix;
  10. int exten;
  11. };
  12. struct Header{
  13. Biobuf *fd;
  14. char err[256];
  15. jmp_buf errlab;
  16. unsigned char buf[3*256];
  17. char vers[8];
  18. unsigned char *globalcmap;
  19. int screenw;
  20. int screenh;
  21. int fields;
  22. int bgrnd;
  23. int aspect;
  24. int flags;
  25. int delay;
  26. int trindex;
  27. int loopcount;
  28. Entry tbl[4096];
  29. Rawimage **array;
  30. Rawimage *new;
  31. unsigned char *pic;
  32. };
  33. static char readerr[] = "ReadGIF: read error: %r";
  34. static char extreaderr[] = "ReadGIF: can't read extension: %r";
  35. static char memerr[] = "ReadGIF: malloc failed: %r";
  36. static Rawimage** readarray(Header*, int);
  37. static Rawimage* readone(Header*);
  38. static void readheader(Header*);
  39. static void skipextension(Header*);
  40. static unsigned char* readcmap(Header*, int);
  41. static unsigned char* decode(Header*, Rawimage*, Entry*);
  42. static void interlace(Header*, Rawimage*);
  43. static
  44. void
  45. _clear(void **p)
  46. {
  47. if(*p){
  48. free(*p);
  49. *p = nil;
  50. }
  51. }
  52. #define clear(p) _clear((void**)p)
  53. static
  54. void
  55. giffreeall(Header *h, int freeimage)
  56. {
  57. int i;
  58. if(h->fd){
  59. Bterm(h->fd);
  60. h->fd = nil;
  61. }
  62. clear(&h->pic);
  63. if(h->new){
  64. clear(&h->new->cmap);
  65. clear(&h->new->chans[0]);
  66. clear(&h->new);
  67. }
  68. clear(&h->globalcmap);
  69. if(freeimage && h->array!=nil){
  70. for(i=0; h->array[i]; i++){
  71. clear(&h->array[i]->cmap);
  72. clear(&h->array[i]->chans[0]);
  73. }
  74. clear(&h->array);
  75. }
  76. }
  77. static
  78. void
  79. giferror(Header *h, char *fmt, ...)
  80. {
  81. va_list arg;
  82. va_start(arg, fmt);
  83. vseprint(h->err, h->err+sizeof h->err, fmt, arg);
  84. va_end(arg);
  85. werrstr("%s", h->err);
  86. giffreeall(h, 1);
  87. longjmp(h->errlab, 1);
  88. }
  89. Rawimage**
  90. readgif(int fd, int colorspace, int justone)
  91. {
  92. Rawimage **a;
  93. Biobuf b;
  94. Header *h;
  95. char buf[ERRMAX];
  96. buf[0] = '\0';
  97. USED(colorspace);
  98. if(Binit(&b, fd, OREAD) < 0)
  99. return nil;
  100. h = malloc(sizeof(Header));
  101. if(h == nil){
  102. Bterm(&b);
  103. return nil;
  104. }
  105. memset(h, 0, sizeof(Header));
  106. h->fd = &b;
  107. sys_errstr(buf, sizeof buf); /* throw it away */
  108. if(setjmp(h->errlab))
  109. a = nil;
  110. else
  111. a = readarray(h, justone);
  112. giffreeall(h, 0);
  113. free(h);
  114. return a;
  115. }
  116. static
  117. void
  118. inittbl(Header *h)
  119. {
  120. int i;
  121. Entry *tbl;
  122. tbl = h->tbl;
  123. for(i=0; i<258; i++) {
  124. tbl[i].prefix = -1;
  125. tbl[i].exten = i;
  126. }
  127. }
  128. static
  129. Rawimage**
  130. readarray(Header *h, int justone)
  131. {
  132. Entry *tbl;
  133. Rawimage *new, **array;
  134. int c, nimages;
  135. tbl = h->tbl;
  136. readheader(h);
  137. if(h->fields & 0x80)
  138. h->globalcmap = readcmap(h, (h->fields&7)+1);
  139. array = malloc(sizeof(Rawimage*));
  140. if(array == nil)
  141. giferror(h, memerr);
  142. nimages = 0;
  143. array[0] = nil;
  144. h->array = array;
  145. for(;;){
  146. switch(c = Bgetc(h->fd)){
  147. case Beof:
  148. goto Return;
  149. case 0x21: /* Extension (ignored) */
  150. skipextension(h);
  151. break;
  152. case 0x2C: /* Image Descriptor */
  153. inittbl(h);
  154. new = readone(h);
  155. if(new->fields & 0x80){
  156. new->cmaplen = 3*(1<<((new->fields&7)+1));
  157. new->cmap = readcmap(h, (new->fields&7)+1);
  158. }else{
  159. if(h->globalcmap == nil)
  160. giferror(h, "ReadGIF: globalcmap missing");
  161. new->cmaplen = 3*(1<<((h->fields&7)+1));
  162. new->cmap = malloc(new->cmaplen);
  163. if(new->cmap == nil)
  164. giferror(h, memerr);
  165. memmove(new->cmap, h->globalcmap, new->cmaplen);
  166. }
  167. h->new = new;
  168. new->chans[0] = decode(h, new, tbl);
  169. if(new->fields & 0x40)
  170. interlace(h, new);
  171. new->gifflags = h->flags;
  172. new->gifdelay = h->delay;
  173. new->giftrindex = h->trindex;
  174. new->gifloopcount = h->loopcount;
  175. array = realloc(h->array, (nimages+2)*sizeof(Rawimage*));
  176. if(array == nil)
  177. giferror(h, memerr);
  178. array[nimages++] = new;
  179. array[nimages] = nil;
  180. h->array = array;
  181. h->new = nil;
  182. if(justone)
  183. goto Return;
  184. break;
  185. case 0x3B: /* Trailer */
  186. goto Return;
  187. default:
  188. fprint(2, "ReadGIF: unknown block type: 0x%.2x\n", c);
  189. goto Return;
  190. }
  191. }
  192. Return:
  193. if(array[0]==nil || array[0]->chans[0] == nil)
  194. giferror(h, "ReadGIF: no picture in file");
  195. return array;
  196. }
  197. static
  198. void
  199. readheader(Header *h)
  200. {
  201. if(Bread(h->fd, h->buf, 13) != 13)
  202. giferror(h, "ReadGIF: can't read header: %r");
  203. memmove(h->vers, h->buf, 6);
  204. if(strcmp(h->vers, "GIF87a")!=0 && strcmp(h->vers, "GIF89a")!=0)
  205. giferror(h, "ReadGIF: can't recognize format %s", h->vers);
  206. h->screenw = h->buf[6]+(h->buf[7]<<8);
  207. h->screenh = h->buf[8]+(h->buf[9]<<8);
  208. h->fields = h->buf[10];
  209. h->bgrnd = h->buf[11];
  210. h->aspect = h->buf[12];
  211. h->flags = 0;
  212. h->delay = 0;
  213. h->trindex = 0;
  214. h->loopcount = -1;
  215. }
  216. static
  217. unsigned char*
  218. readcmap(Header *h, int size)
  219. {
  220. unsigned char *map;
  221. if(size > 8)
  222. giferror(h, "ReadGIF: can't handles %d bits per pixel", size);
  223. size = 3*(1<<size);
  224. if(Bread(h->fd, h->buf, size) != size)
  225. giferror(h, "ReadGIF: short read on color map");
  226. map = malloc(size);
  227. if(map == nil)
  228. giferror(h, memerr);
  229. memmove(map, h->buf, size);
  230. return map;
  231. }
  232. static
  233. Rawimage*
  234. readone(Header *h)
  235. {
  236. Rawimage *i;
  237. int left, top, width, height;
  238. if(Bread(h->fd, h->buf, 9) != 9)
  239. giferror(h, "ReadGIF: can't read image descriptor: %r");
  240. i = malloc(sizeof(Rawimage));
  241. if(i == nil)
  242. giferror(h, memerr);
  243. left = h->buf[0]+(h->buf[1]<<8);
  244. top = h->buf[2]+(h->buf[3]<<8);
  245. width = h->buf[4]+(h->buf[5]<<8);
  246. height = h->buf[6]+(h->buf[7]<<8);
  247. i->fields = h->buf[8];
  248. i->r.min.x = left;
  249. i->r.min.y = top;
  250. i->r.max.x = left+width;
  251. i->r.max.y = top+height;
  252. i->nchans = 1;
  253. i->chandesc = CRGB1;
  254. memset(i->chans, 0, sizeof(i->chans));
  255. return i;
  256. }
  257. static
  258. int
  259. readdata(Header *h, unsigned char *data)
  260. {
  261. int nbytes, n;
  262. nbytes = Bgetc(h->fd);
  263. if(nbytes < 0)
  264. giferror(h, "ReadGIF: can't read data: %r");
  265. if(nbytes == 0)
  266. return 0;
  267. n = Bread(h->fd, data, nbytes);
  268. if(n < 0)
  269. giferror(h, "ReadGIF: can't read data: %r");
  270. if(n != nbytes)
  271. fprint(2, "ReadGIF: short data subblock\n");
  272. return n;
  273. }
  274. static
  275. void
  276. graphiccontrol(Header *h)
  277. {
  278. if(Bread(h->fd, h->buf, 5+1) != 5+1)
  279. giferror(h, readerr);
  280. h->flags = h->buf[1];
  281. h->delay = h->buf[2]+(h->buf[3]<<8);
  282. h->trindex = h->buf[4];
  283. }
  284. static
  285. void
  286. skipextension(Header *h)
  287. {
  288. int type, hsize, hasdata, n;
  289. unsigned char data[256];
  290. hsize = 0;
  291. hasdata = 0;
  292. type = Bgetc(h->fd);
  293. switch(type){
  294. case Beof:
  295. giferror(h, extreaderr);
  296. break;
  297. case 0x01: /* Plain Text Extension */
  298. hsize = 13;
  299. hasdata = 1;
  300. break;
  301. case 0xF9: /* Graphic Control Extension */
  302. graphiccontrol(h);
  303. return;
  304. case 0xFE: /* Comment Extension */
  305. hasdata = 1;
  306. break;
  307. case 0xFF: /* Application Extension */
  308. hsize = Bgetc(h->fd);
  309. /* standard says this must be 11, but Adobe likes to put out 10-byte ones,
  310. * so we pay attention to the field. */
  311. hasdata = 1;
  312. break;
  313. default:
  314. giferror(h, "ReadGIF: unknown extension");
  315. }
  316. if(hsize>0 && Bread(h->fd, h->buf, hsize) != hsize)
  317. giferror(h, extreaderr);
  318. if(!hasdata){
  319. /*
  320. * This code used to check h->buf[hsize-1] != 0
  321. * and giferror if so, but if !hasdata, hsize == 0.
  322. */
  323. return;
  324. }
  325. /* loop counter: Application Extension with NETSCAPE2.0 as string and 1 <loop.count> in data */
  326. if(type == 0xFF && hsize==11 && memcmp(h->buf, "NETSCAPE2.0", 11)==0){
  327. n = readdata(h, data);
  328. if(n == 0)
  329. return;
  330. if(n==3 && data[0]==1)
  331. h->loopcount = data[1] | (data[2]<<8);
  332. }
  333. while(readdata(h, data) != 0)
  334. ;
  335. }
  336. static
  337. unsigned char*
  338. decode(Header *h, Rawimage *i, Entry *tbl)
  339. {
  340. int c, incode, codesize, CTM, EOD, pici, datai, stacki, nbits, sreg, fc, code, piclen;
  341. int csize, nentry, maxentry, first, ocode, ndata, nb;
  342. unsigned char clip, *p, *pic;
  343. unsigned char stack[4096], data[256];
  344. if(Bread(h->fd, h->buf, 1) != 1)
  345. giferror(h, "ReadGIF: can't read data: %r");
  346. codesize = h->buf[0];
  347. if(codesize>8 || 0>codesize)
  348. giferror(h, "ReadGIF: can't handle codesize %d", codesize);
  349. CTM =1<<codesize;
  350. EOD = CTM+1;
  351. piclen = (i->r.max.x-i->r.min.x)*(i->r.max.y-i->r.min.y);
  352. i->chanlen = piclen;
  353. pic = malloc(piclen);
  354. if(pic == nil)
  355. giferror(h, memerr);
  356. h->pic = pic;
  357. pici = 0;
  358. ndata = 0;
  359. datai = 0;
  360. nbits = 0;
  361. sreg = 0;
  362. fc = 0;
  363. Loop:
  364. for(;;){
  365. csize = codesize+1;
  366. nentry = EOD+1;
  367. maxentry = (1<<csize)-1;
  368. first = 1;
  369. ocode = -1;
  370. for(;; ocode = incode) {
  371. while(nbits < csize) {
  372. if(datai == ndata){
  373. ndata = readdata(h, data);
  374. if(ndata == 0)
  375. goto Return;
  376. datai = 0;
  377. }
  378. c = data[datai++];
  379. sreg |= c<<nbits;
  380. nbits += 8;
  381. }
  382. code = sreg & ((1<<csize) - 1);
  383. sreg >>= csize;
  384. nbits -= csize;
  385. if(code == EOD){
  386. ndata = readdata(h, data);
  387. if(ndata != 0)
  388. fprint(2, "ReadGIF: unexpected data past EOD\n");
  389. goto Return;
  390. }
  391. if(code == CTM)
  392. goto Loop;
  393. stacki = (sizeof stack)-1;
  394. incode = code;
  395. /* special case for KwKwK */
  396. if(code == nentry) {
  397. stack[stacki--] = fc;
  398. code = ocode;
  399. }
  400. if(code > nentry){
  401. fprint(2, "ReadGIF: GIF invalid, code out of range, %x > %x\n", code, nentry);
  402. code = nentry;
  403. }
  404. for(c=code; stacki>0 && c>=0; c=tbl[c].prefix)
  405. stack[stacki--] = tbl[c].exten;
  406. nb = (sizeof stack)-(stacki+1);
  407. if(pici+nb > piclen){
  408. /* this common error is harmless
  409. * we have to keep reading to keep the blocks in sync */
  410. ;
  411. }else{
  412. memmove(pic+pici, stack+stacki+1, sizeof stack - (stacki+1));
  413. pici += nb;
  414. }
  415. fc = stack[stacki+1];
  416. if(first){
  417. first = 0;
  418. continue;
  419. }
  420. #define early 0 /* peculiar tiff feature here for reference */
  421. if(nentry == maxentry-early) {
  422. if(csize >= 12)
  423. continue;
  424. csize++;
  425. maxentry = (1<<csize);
  426. if(csize < 12)
  427. maxentry--;
  428. }
  429. tbl[nentry].prefix = ocode;
  430. tbl[nentry].exten = fc;
  431. nentry++;
  432. }
  433. }
  434. Return:
  435. if(i->cmap!=nil && i->cmaplen!=3*256){
  436. clip = (i->cmaplen/3)-1;
  437. for(p = pic; p < pic+piclen; p++)
  438. if(*p > clip)
  439. *p = clip;
  440. }
  441. h->pic = nil;
  442. return pic;
  443. }
  444. static
  445. void
  446. interlace(Header *h, Rawimage *image)
  447. {
  448. unsigned char *pic;
  449. Rectangle r;
  450. int dx, yy, y;
  451. unsigned char *ipic;
  452. pic = image->chans[0];
  453. r = image->r;
  454. dx = r.max.x-r.min.x;
  455. ipic = malloc(dx*(r.max.y-r.min.y));
  456. if(ipic == nil)
  457. giferror(h, nil);
  458. /* Group 1: every 8th row, starting with row 0 */
  459. yy = 0;
  460. for(y=r.min.y; y<r.max.y; y+=8){
  461. memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
  462. yy++;
  463. }
  464. /* Group 2: every 8th row, starting with row 4 */
  465. for(y=r.min.y+4; y<r.max.y; y+=8){
  466. memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
  467. yy++;
  468. }
  469. /* Group 3: every 4th row, starting with row 2 */
  470. for(y=r.min.y+2; y<r.max.y; y+=4){
  471. memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
  472. yy++;
  473. }
  474. /* Group 4: every 2nd row, starting with row 1 */
  475. for(y=r.min.y+1; y<r.max.y; y+=2){
  476. memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
  477. yy++;
  478. }
  479. free(image->chans[0]);
  480. image->chans[0] = ipic;
  481. }