dssread.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 "sky.h"
  13. static void dodecode(Biobuf*, Pix*, int, int, uint8_t*);
  14. static int32_t getlong(uint8_t*);
  15. int debug;
  16. Img*
  17. dssread(char *file)
  18. {
  19. int nx, ny, scale, sumall;
  20. Pix *p, *pend;
  21. uint8_t buf[21];
  22. Biobuf *bp;
  23. Img *ip;
  24. if(debug)
  25. Bprint(&bout, "reading %s\n", file);
  26. bp = Bopen(file, OREAD);
  27. if(bp == 0)
  28. return 0;
  29. if(Bread(bp, buf, sizeof(buf)) != sizeof(buf) ||
  30. buf[0] != 0xdd || buf[1] != 0x99){
  31. werrstr("bad format");
  32. return 0;
  33. }
  34. nx = getlong(buf+2);
  35. ny = getlong(buf+6);
  36. scale = getlong(buf+10);
  37. sumall = getlong(buf+14);
  38. if(debug)
  39. fprint(2, "%s: nx=%d, ny=%d, scale=%d, sumall=%d, nbitplanes=%d,%d,%d\n",
  40. file, nx, ny, scale, sumall, buf[18], buf[19], buf[20]);
  41. ip = malloc(sizeof(Img) + (nx*ny-1)*sizeof(int));
  42. if(ip == 0){
  43. Bterm(bp);
  44. werrstr("no memory");
  45. return 0;
  46. }
  47. ip->nx = nx;
  48. ip->ny = ny;
  49. dodecode(bp, ip->a, nx, ny, buf+18);
  50. ip->a[0] = sumall; /* sum of all pixels */
  51. Bterm(bp);
  52. if(scale > 1){
  53. p = ip->a;
  54. pend = &ip->a[nx*ny];
  55. while(p < pend)
  56. *p++ *= scale;
  57. }
  58. hinv(ip->a, nx, ny);
  59. return ip;
  60. }
  61. static
  62. void
  63. dodecode(Biobuf *infile, Pix *a, int nx, int ny, uint8_t *nbitplanes)
  64. {
  65. int nel, nx2, ny2, bits, mask;
  66. Pix *aend, px;
  67. nel = nx*ny;
  68. nx2 = (nx+1)/2;
  69. ny2 = (ny+1)/2;
  70. memset(a, 0, nel*sizeof(*a));
  71. /*
  72. * Initialize bit input
  73. */
  74. start_inputing_bits();
  75. /*
  76. * read bit planes for each quadrant
  77. */
  78. qtree_decode(infile, &a[0], ny, nx2, ny2, nbitplanes[0]);
  79. qtree_decode(infile, &a[ny2], ny, nx2, ny/2, nbitplanes[1]);
  80. qtree_decode(infile, &a[ny*nx2], ny, nx/2, ny2, nbitplanes[1]);
  81. qtree_decode(infile, &a[ny*nx2+ny2], ny, nx/2, ny/2, nbitplanes[2]);
  82. /*
  83. * make sure there is an EOF symbol (nybble=0) at end
  84. */
  85. if(input_nybble(infile) != 0){
  86. fprint(2, "dodecode: bad bit plane values\n");
  87. exits("format");
  88. }
  89. /*
  90. * get the sign bits
  91. */
  92. aend = &a[nel];
  93. mask = 0;
  94. bits = 0;;
  95. for(; a<aend; a++) {
  96. if(px = *a) {
  97. if(mask == 0) {
  98. mask = 0x80;
  99. bits = Bgetc(infile);
  100. }
  101. if(mask & bits)
  102. *a = -px;
  103. mask >>= 1;
  104. }
  105. }
  106. }
  107. static
  108. int32_t getlong(uint8_t *p)
  109. {
  110. return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
  111. }