cread.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "lib9.h"
  2. #include "draw.h"
  3. #include "memdraw.h"
  4. Memimage*
  5. creadmemimage(int fd)
  6. {
  7. char hdr[5*12+1];
  8. Rectangle r;
  9. int m, nb, miny, maxy, new, ldepth, ncblock;
  10. uchar *buf;
  11. Memimage *i;
  12. ulong chan;
  13. if(readn(fd, hdr, 5*12) != 5*12){
  14. werrstr("readmemimage: short header (2)");
  15. return nil;
  16. }
  17. /*
  18. * distinguish new channel descriptor from old ldepth.
  19. * channel descriptors have letters as well as numbers,
  20. * while ldepths are a single digit formatted as %-11d.
  21. */
  22. new = 0;
  23. for(m=0; m<10; m++){
  24. if(hdr[m] != ' '){
  25. new = 1;
  26. break;
  27. }
  28. }
  29. if(hdr[11] != ' '){
  30. werrstr("creadimage: bad format");
  31. return nil;
  32. }
  33. if(new){
  34. hdr[11] = '\0';
  35. if((chan = strtochan(hdr)) == 0){
  36. werrstr("creadimage: bad channel string %s", hdr);
  37. return nil;
  38. }
  39. }else{
  40. ldepth = ((int)hdr[10])-'0';
  41. if(ldepth<0 || ldepth>3){
  42. werrstr("creadimage: bad ldepth %d", ldepth);
  43. return nil;
  44. }
  45. chan = drawld2chan[ldepth];
  46. }
  47. r.min.x=atoi(hdr+1*12);
  48. r.min.y=atoi(hdr+2*12);
  49. r.max.x=atoi(hdr+3*12);
  50. r.max.y=atoi(hdr+4*12);
  51. if(r.min.x>r.max.x || r.min.y>r.max.y){
  52. werrstr("creadimage: bad rectangle");
  53. return nil;
  54. }
  55. i = allocmemimage(r, chan);
  56. if(i == nil)
  57. return nil;
  58. ncblock = _compblocksize(r, i->depth);
  59. buf = malloc(ncblock);
  60. if(buf == nil)
  61. goto Errout;
  62. miny = r.min.y;
  63. while(miny != r.max.y){
  64. if(readn(fd, hdr, 2*12) != 2*12){
  65. Shortread:
  66. werrstr("readmemimage: short read");
  67. Errout:
  68. freememimage(i);
  69. free(buf);
  70. return nil;
  71. }
  72. maxy = atoi(hdr+0*12);
  73. nb = atoi(hdr+1*12);
  74. if(maxy<=miny || r.max.y<maxy){
  75. werrstr("readimage: bad maxy %d", maxy);
  76. goto Errout;
  77. }
  78. if(nb<=0 || ncblock<nb){
  79. werrstr("readimage: bad count %d", nb);
  80. goto Errout;
  81. }
  82. if(readn(fd, buf, nb)!=nb)
  83. goto Shortread;
  84. if(!new) /* old image: flip the data bits */
  85. _twiddlecompressed(buf, nb);
  86. cloadmemimage(i, Rect(r.min.x, miny, r.max.x, maxy), buf, nb);
  87. miny = maxy;
  88. }
  89. free(buf);
  90. return i;
  91. }