Chops.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * basic channel operations
  6. *
  7. * history:
  8. * 1996-03-28 fl Created
  9. * 1996-08-13 fl Added and/or/xor for "1" images
  10. * 1996-12-14 fl Added add_modulo, sub_modulo
  11. * 2005-09-10 fl Fixed output values from and/or/xor
  12. *
  13. * Copyright (c) 1996 by Fredrik Lundh.
  14. * Copyright (c) 1997 by Secret Labs AB.
  15. *
  16. * See the README file for details on usage and redistribution.
  17. */
  18. #include "Imaging.h"
  19. #define CHOP(operation) \
  20. int x, y; \
  21. Imaging imOut; \
  22. imOut = create(imIn1, imIn2, NULL); \
  23. if (!imOut) { \
  24. return NULL; \
  25. } \
  26. for (y = 0; y < imOut->ysize; y++) { \
  27. UINT8 *out = (UINT8 *)imOut->image[y]; \
  28. UINT8 *in1 = (UINT8 *)imIn1->image[y]; \
  29. UINT8 *in2 = (UINT8 *)imIn2->image[y]; \
  30. for (x = 0; x < imOut->linesize; x++) { \
  31. int temp = operation; \
  32. if (temp <= 0) { \
  33. out[x] = 0; \
  34. } else if (temp >= 255) { \
  35. out[x] = 255; \
  36. } else { \
  37. out[x] = temp; \
  38. } \
  39. } \
  40. } \
  41. return imOut;
  42. #define CHOP2(operation, mode) \
  43. int x, y; \
  44. Imaging imOut; \
  45. imOut = create(imIn1, imIn2, mode); \
  46. if (!imOut) { \
  47. return NULL; \
  48. } \
  49. for (y = 0; y < imOut->ysize; y++) { \
  50. UINT8 *out = (UINT8 *)imOut->image[y]; \
  51. UINT8 *in1 = (UINT8 *)imIn1->image[y]; \
  52. UINT8 *in2 = (UINT8 *)imIn2->image[y]; \
  53. for (x = 0; x < imOut->linesize; x++) { \
  54. out[x] = operation; \
  55. } \
  56. } \
  57. return imOut;
  58. static Imaging
  59. create(Imaging im1, Imaging im2, char *mode) {
  60. int xsize, ysize;
  61. if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 ||
  62. (mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) {
  63. return (Imaging)ImagingError_ModeError();
  64. }
  65. if (im1->type != im2->type || im1->bands != im2->bands) {
  66. return (Imaging)ImagingError_Mismatch();
  67. }
  68. xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize;
  69. ysize = (im1->ysize < im2->ysize) ? im1->ysize : im2->ysize;
  70. return ImagingNewDirty(im1->mode, xsize, ysize);
  71. }
  72. Imaging
  73. ImagingChopLighter(Imaging imIn1, Imaging imIn2) {
  74. CHOP((in1[x] > in2[x]) ? in1[x] : in2[x]);
  75. }
  76. Imaging
  77. ImagingChopDarker(Imaging imIn1, Imaging imIn2) {
  78. CHOP((in1[x] < in2[x]) ? in1[x] : in2[x]);
  79. }
  80. Imaging
  81. ImagingChopDifference(Imaging imIn1, Imaging imIn2) {
  82. CHOP(abs((int)in1[x] - (int)in2[x]));
  83. }
  84. Imaging
  85. ImagingChopMultiply(Imaging imIn1, Imaging imIn2) {
  86. CHOP((int)in1[x] * (int)in2[x] / 255);
  87. }
  88. Imaging
  89. ImagingChopScreen(Imaging imIn1, Imaging imIn2) {
  90. CHOP(255 - ((int)(255 - in1[x]) * (int)(255 - in2[x])) / 255);
  91. }
  92. Imaging
  93. ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset) {
  94. CHOP(((int)in1[x] + (int)in2[x]) / scale + offset);
  95. }
  96. Imaging
  97. ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset) {
  98. CHOP(((int)in1[x] - (int)in2[x]) / scale + offset);
  99. }
  100. Imaging
  101. ImagingChopAnd(Imaging imIn1, Imaging imIn2) {
  102. CHOP2((in1[x] && in2[x]) ? 255 : 0, "1");
  103. }
  104. Imaging
  105. ImagingChopOr(Imaging imIn1, Imaging imIn2) {
  106. CHOP2((in1[x] || in2[x]) ? 255 : 0, "1");
  107. }
  108. Imaging
  109. ImagingChopXor(Imaging imIn1, Imaging imIn2) {
  110. CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, "1");
  111. }
  112. Imaging
  113. ImagingChopAddModulo(Imaging imIn1, Imaging imIn2) {
  114. CHOP2(in1[x] + in2[x], NULL);
  115. }
  116. Imaging
  117. ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2) {
  118. CHOP2(in1[x] - in2[x], NULL);
  119. }
  120. Imaging
  121. ImagingChopSoftLight(Imaging imIn1, Imaging imIn2) {
  122. CHOP2(
  123. (((255 - in1[x]) * (in1[x] * in2[x])) / 65536) +
  124. (in1[x] * (255 - ((255 - in1[x]) * (255 - in2[x]) / 255))) / 255,
  125. NULL);
  126. }
  127. Imaging
  128. ImagingChopHardLight(Imaging imIn1, Imaging imIn2) {
  129. CHOP2(
  130. (in2[x] < 128) ? ((in1[x] * in2[x]) / 127)
  131. : 255 - (((255 - in2[x]) * (255 - in1[x])) / 127),
  132. NULL);
  133. }
  134. Imaging
  135. ImagingOverlay(Imaging imIn1, Imaging imIn2) {
  136. CHOP2(
  137. (in1[x] < 128) ? ((in1[x] * in2[x]) / 127)
  138. : 255 - (((255 - in1[x]) * (255 - in2[x])) / 127),
  139. NULL);
  140. }