Bands.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * stuff to extract and paste back individual bands
  6. *
  7. * history:
  8. * 1996-03-20 fl Created
  9. * 1997-08-27 fl Fixed putband for single band targets.
  10. * 2003-09-26 fl Fixed getband/putband for 2-band images (LA, PA).
  11. *
  12. * Copyright (c) 1997-2003 by Secret Labs AB.
  13. * Copyright (c) 1996-1997 by Fredrik Lundh.
  14. *
  15. * See the README file for details on usage and redistribution.
  16. */
  17. #include "Imaging.h"
  18. Imaging
  19. ImagingGetBand(Imaging imIn, int band)
  20. {
  21. Imaging imOut;
  22. int x, y;
  23. /* Check arguments */
  24. if (!imIn || imIn->type != IMAGING_TYPE_UINT8)
  25. return (Imaging) ImagingError_ModeError();
  26. if (band < 0 || band >= imIn->bands)
  27. return (Imaging) ImagingError_ValueError("band index out of range");
  28. /* Shortcuts */
  29. if (imIn->bands == 1)
  30. return ImagingCopy(imIn);
  31. /* Special case for LXXA etc */
  32. if (imIn->bands == 2 && band == 1)
  33. band = 3;
  34. imOut = ImagingNewDirty("L", imIn->xsize, imIn->ysize);
  35. if (!imOut)
  36. return NULL;
  37. /* Extract band from image */
  38. for (y = 0; y < imIn->ysize; y++) {
  39. UINT8* in = (UINT8*) imIn->image[y] + band;
  40. UINT8* out = imOut->image8[y];
  41. x = 0;
  42. for (; x < imIn->xsize - 3; x += 4) {
  43. UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
  44. memcpy(out + x, &v, sizeof(v));
  45. in += 16;
  46. }
  47. for (; x < imIn->xsize; x++) {
  48. out[x] = *in;
  49. in += 4;
  50. }
  51. }
  52. return imOut;
  53. }
  54. int
  55. ImagingSplit(Imaging imIn, Imaging bands[4])
  56. {
  57. int i, j, x, y;
  58. /* Check arguments */
  59. if (!imIn || imIn->type != IMAGING_TYPE_UINT8) {
  60. (void) ImagingError_ModeError();
  61. return 0;
  62. }
  63. /* Shortcuts */
  64. if (imIn->bands == 1) {
  65. bands[0] = ImagingCopy(imIn);
  66. return imIn->bands;
  67. }
  68. for (i = 0; i < imIn->bands; i++) {
  69. bands[i] = ImagingNewDirty("L", imIn->xsize, imIn->ysize);
  70. if ( ! bands[i]) {
  71. for (j = 0; j < i; ++j) {
  72. ImagingDelete(bands[j]);
  73. }
  74. return 0;
  75. }
  76. }
  77. /* Extract bands from image */
  78. if (imIn->bands == 2) {
  79. for (y = 0; y < imIn->ysize; y++) {
  80. UINT8* in = (UINT8*) imIn->image[y];
  81. UINT8* out0 = bands[0]->image8[y];
  82. UINT8* out1 = bands[1]->image8[y];
  83. x = 0;
  84. for (; x < imIn->xsize - 3; x += 4) {
  85. UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
  86. memcpy(out0 + x, &v, sizeof(v));
  87. v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]);
  88. memcpy(out1 + x, &v, sizeof(v));
  89. in += 16;
  90. }
  91. for (; x < imIn->xsize; x++) {
  92. out0[x] = in[0];
  93. out1[x] = in[3];
  94. in += 4;
  95. }
  96. }
  97. } else if (imIn->bands == 3) {
  98. for (y = 0; y < imIn->ysize; y++) {
  99. UINT8* in = (UINT8*) imIn->image[y];
  100. UINT8* out0 = bands[0]->image8[y];
  101. UINT8* out1 = bands[1]->image8[y];
  102. UINT8* out2 = bands[2]->image8[y];
  103. x = 0;
  104. for (; x < imIn->xsize - 3; x += 4) {
  105. UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
  106. memcpy(out0 + x, &v, sizeof(v));
  107. v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]);
  108. memcpy(out1 + x, &v, sizeof(v));
  109. v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]);
  110. memcpy(out2 + x, &v, sizeof(v));
  111. in += 16;
  112. }
  113. for (; x < imIn->xsize; x++) {
  114. out0[x] = in[0];
  115. out1[x] = in[1];
  116. out2[x] = in[2];
  117. in += 4;
  118. }
  119. }
  120. } else {
  121. for (y = 0; y < imIn->ysize; y++) {
  122. UINT8* in = (UINT8*) imIn->image[y];
  123. UINT8* out0 = bands[0]->image8[y];
  124. UINT8* out1 = bands[1]->image8[y];
  125. UINT8* out2 = bands[2]->image8[y];
  126. UINT8* out3 = bands[3]->image8[y];
  127. x = 0;
  128. for (; x < imIn->xsize - 3; x += 4) {
  129. UINT32 v = MAKE_UINT32(in[0], in[4], in[8], in[12]);
  130. memcpy(out0 + x, &v, sizeof(v));
  131. v = MAKE_UINT32(in[0+1], in[4+1], in[8+1], in[12+1]);
  132. memcpy(out1 + x, &v, sizeof(v));
  133. v = MAKE_UINT32(in[0+2], in[4+2], in[8+2], in[12+2]);
  134. memcpy(out2 + x, &v, sizeof(v));
  135. v = MAKE_UINT32(in[0+3], in[4+3], in[8+3], in[12+3]);
  136. memcpy(out3 + x, &v, sizeof(v));
  137. in += 16;
  138. }
  139. for (; x < imIn->xsize; x++) {
  140. out0[x] = in[0];
  141. out1[x] = in[1];
  142. out2[x] = in[2];
  143. out3[x] = in[3];
  144. in += 4;
  145. }
  146. }
  147. }
  148. return imIn->bands;
  149. }
  150. Imaging
  151. ImagingPutBand(Imaging imOut, Imaging imIn, int band)
  152. {
  153. int x, y;
  154. /* Check arguments */
  155. if (!imIn || imIn->bands != 1 || !imOut)
  156. return (Imaging) ImagingError_ModeError();
  157. if (band < 0 || band >= imOut->bands)
  158. return (Imaging) ImagingError_ValueError("band index out of range");
  159. if (imIn->type != imOut->type ||
  160. imIn->xsize != imOut->xsize ||
  161. imIn->ysize != imOut->ysize)
  162. return (Imaging) ImagingError_Mismatch();
  163. /* Shortcuts */
  164. if (imOut->bands == 1)
  165. return ImagingCopy2(imOut, imIn);
  166. /* Special case for LXXA etc */
  167. if (imOut->bands == 2 && band == 1)
  168. band = 3;
  169. /* Insert band into image */
  170. for (y = 0; y < imIn->ysize; y++) {
  171. UINT8* in = imIn->image8[y];
  172. UINT8* out = (UINT8*) imOut->image[y] + band;
  173. for (x = 0; x < imIn->xsize; x++) {
  174. *out = in[x];
  175. out += 4;
  176. }
  177. }
  178. return imOut;
  179. }
  180. Imaging
  181. ImagingFillBand(Imaging imOut, int band, int color)
  182. {
  183. int x, y;
  184. /* Check arguments */
  185. if (!imOut || imOut->type != IMAGING_TYPE_UINT8)
  186. return (Imaging) ImagingError_ModeError();
  187. if (band < 0 || band >= imOut->bands)
  188. return (Imaging) ImagingError_ValueError("band index out of range");
  189. /* Special case for LXXA etc */
  190. if (imOut->bands == 2 && band == 1)
  191. band = 3;
  192. color = CLIP8(color);
  193. /* Insert color into image */
  194. for (y = 0; y < imOut->ysize; y++) {
  195. UINT8* out = (UINT8*) imOut->image[y] + band;
  196. for (x = 0; x < imOut->xsize; x++) {
  197. *out = (UINT8) color;
  198. out += 4;
  199. }
  200. }
  201. return imOut;
  202. }
  203. Imaging
  204. ImagingMerge(const char* mode, Imaging bands[4])
  205. {
  206. int i, x, y;
  207. int bandsCount = 0;
  208. Imaging imOut;
  209. Imaging firstBand;
  210. firstBand = bands[0];
  211. if ( ! firstBand) {
  212. return (Imaging) ImagingError_ValueError("wrong number of bands");
  213. }
  214. for (i = 0; i < 4; ++i) {
  215. if ( ! bands[i]) {
  216. break;
  217. }
  218. if (bands[i]->bands != 1) {
  219. return (Imaging) ImagingError_ModeError();
  220. }
  221. if (bands[i]->xsize != firstBand->xsize
  222. || bands[i]->ysize != firstBand->ysize) {
  223. return (Imaging) ImagingError_Mismatch();
  224. }
  225. }
  226. bandsCount = i;
  227. imOut = ImagingNewDirty(mode, firstBand->xsize, firstBand->ysize);
  228. if ( ! imOut)
  229. return NULL;
  230. if (imOut->bands != bandsCount) {
  231. ImagingDelete(imOut);
  232. return (Imaging) ImagingError_ValueError("wrong number of bands");
  233. }
  234. if (imOut->bands == 1)
  235. return ImagingCopy2(imOut, firstBand);
  236. if (imOut->bands == 2) {
  237. for (y = 0; y < imOut->ysize; y++) {
  238. UINT8* in0 = bands[0]->image8[y];
  239. UINT8* in1 = bands[1]->image8[y];
  240. UINT32* out = (UINT32*) imOut->image32[y];
  241. for (x = 0; x < imOut->xsize; x++) {
  242. out[x] = MAKE_UINT32(in0[x], 0, 0, in1[x]);
  243. }
  244. }
  245. } else if (imOut->bands == 3) {
  246. for (y = 0; y < imOut->ysize; y++) {
  247. UINT8* in0 = bands[0]->image8[y];
  248. UINT8* in1 = bands[1]->image8[y];
  249. UINT8* in2 = bands[2]->image8[y];
  250. UINT32* out = (UINT32*) imOut->image32[y];
  251. for (x = 0; x < imOut->xsize; x++) {
  252. out[x] = MAKE_UINT32(in0[x], in1[x], in2[x], 0);
  253. }
  254. }
  255. } else if (imOut->bands == 4) {
  256. for (y = 0; y < imOut->ysize; y++) {
  257. UINT8* in0 = bands[0]->image8[y];
  258. UINT8* in1 = bands[1]->image8[y];
  259. UINT8* in2 = bands[2]->image8[y];
  260. UINT8* in3 = bands[3]->image8[y];
  261. UINT32* out = (UINT32*) imOut->image32[y];
  262. for (x = 0; x < imOut->xsize; x++) {
  263. out[x] = MAKE_UINT32(in0[x], in1[x], in2[x], in3[x]);
  264. }
  265. }
  266. }
  267. return imOut;
  268. }