dither_image.ino 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #include "dither_image.h"
  2. void dither_image(camera_fb_t* frame_buffer) {
  3. for (uint8_t y = 0; y < frame_buffer->height; ++y) {
  4. for (uint8_t x = 0; x < frame_buffer->width; ++x) {
  5. size_t current = (y * frame_buffer->width) + x;
  6. uint8_t oldpixel = frame_buffer->buf[current];
  7. uint8_t newpixel = oldpixel >= 128 ? 255 : 0;
  8. frame_buffer->buf[current] = newpixel;
  9. int8_t quant_error = oldpixel - newpixel;
  10. // Apply error diffusion based on the selected algorithm
  11. switch (camera_model.ditherAlgorithm) {
  12. case JARVIS_JUDICE_NINKE:
  13. frame_buffer->buf[(y * frame_buffer->width) + x + 1] +=
  14. quant_error * 7 / 48;
  15. frame_buffer->buf[(y * frame_buffer->width) + x + 2] +=
  16. quant_error * 5 / 48;
  17. frame_buffer->buf[(y + 1) * frame_buffer->width + x - 2] +=
  18. quant_error * 3 / 48;
  19. frame_buffer->buf[(y + 1) * frame_buffer->width + x - 1] +=
  20. quant_error * 5 / 48;
  21. frame_buffer->buf[(y + 1) * frame_buffer->width + x] +=
  22. quant_error * 7 / 48;
  23. frame_buffer->buf[(y + 1) * frame_buffer->width + x + 1] +=
  24. quant_error * 5 / 48;
  25. frame_buffer->buf[(y + 1) * frame_buffer->width + x + 2] +=
  26. quant_error * 3 / 48;
  27. frame_buffer->buf[(y + 2) * frame_buffer->width + x - 2] +=
  28. quant_error * 1 / 48;
  29. frame_buffer->buf[(y + 2) * frame_buffer->width + x - 1] +=
  30. quant_error * 3 / 48;
  31. frame_buffer->buf[(y + 2) * frame_buffer->width + x] +=
  32. quant_error * 5 / 48;
  33. frame_buffer->buf[(y + 2) * frame_buffer->width + x + 1] +=
  34. quant_error * 3 / 48;
  35. frame_buffer->buf[(y + 2) * frame_buffer->width + x + 2] +=
  36. quant_error * 1 / 48;
  37. break;
  38. case STUCKI:
  39. frame_buffer->buf[(y * frame_buffer->width) + x + 1] +=
  40. quant_error * 8 / 42;
  41. frame_buffer->buf[(y * frame_buffer->width) + x + 2] +=
  42. quant_error * 4 / 42;
  43. frame_buffer->buf[(y + 1) * frame_buffer->width + x - 2] +=
  44. quant_error * 2 / 42;
  45. frame_buffer->buf[(y + 1) * frame_buffer->width + x - 1] +=
  46. quant_error * 4 / 42;
  47. frame_buffer->buf[(y + 1) * frame_buffer->width + x] +=
  48. quant_error * 8 / 42;
  49. frame_buffer->buf[(y + 1) * frame_buffer->width + x + 1] +=
  50. quant_error * 4 / 42;
  51. frame_buffer->buf[(y + 1) * frame_buffer->width + x + 2] +=
  52. quant_error * 2 / 42;
  53. frame_buffer->buf[(y + 2) * frame_buffer->width + x - 2] +=
  54. quant_error * 1 / 42;
  55. frame_buffer->buf[(y + 2) * frame_buffer->width + x - 1] +=
  56. quant_error * 2 / 42;
  57. frame_buffer->buf[(y + 2) * frame_buffer->width + x] +=
  58. quant_error * 4 / 42;
  59. frame_buffer->buf[(y + 2) * frame_buffer->width + x + 1] +=
  60. quant_error * 2 / 42;
  61. frame_buffer->buf[(y + 2) * frame_buffer->width + x + 2] +=
  62. quant_error * 1 / 42;
  63. break;
  64. case FLOYD_STEINBERG:
  65. default:
  66. // Default to Floyd-Steinberg dithering if an invalid
  67. // algorithm is selected
  68. frame_buffer->buf[(y * frame_buffer->width) + x + 1] +=
  69. quant_error * 7 / 16;
  70. frame_buffer->buf[(y + 1) * frame_buffer->width + x - 1] +=
  71. quant_error * 3 / 16;
  72. frame_buffer->buf[(y + 1) * frame_buffer->width + x] +=
  73. quant_error * 5 / 16;
  74. frame_buffer->buf[(y + 1) * frame_buffer->width + x + 1] +=
  75. quant_error * 1 / 16;
  76. break;
  77. }
  78. }
  79. }
  80. }