readgif.c 11 KB

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