Bands.c 8.8 KB

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