您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

160 行
4.7 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2004-2014 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include "core.h"
  14. #include "image-private.h"
  15. namespace lol
  16. {
  17. static vec4 u8tof32(u8vec4 pixel)
  18. {
  19. //vec4 ret;
  20. //ret.r = pow((float)pixel.r / 255.f, global_gamma);
  21. //ret.g = pow((float)pixel.g / 255.f, global_gamma);
  22. //ret.b = pow((float)pixel.b / 255.f, global_gamma);
  23. return (vec4)pixel / 255.f;
  24. }
  25. static u8vec4 f32tou8(vec4 pixel)
  26. {
  27. return (u8vec4)(pixel * 255.99f);
  28. }
  29. /*
  30. * Pixel-level image manipulation
  31. */
  32. PixelFormat Image::GetFormat() const
  33. {
  34. return m_data->m_format;
  35. }
  36. void Image::SetFormat(PixelFormat fmt)
  37. {
  38. PixelFormat old_fmt = m_data->m_format;
  39. /* Preliminary intermediate conversions */
  40. if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::Y_F32)
  41. SetFormat(PixelFormat::RGBA_F32);
  42. else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::Y_F32)
  43. SetFormat(PixelFormat::RGBA_F32);
  44. else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGBA_8)
  45. SetFormat(PixelFormat::RGBA_F32);
  46. else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGB_8)
  47. SetFormat(PixelFormat::RGBA_F32);
  48. old_fmt = m_data->m_format;
  49. /* Set the new active pixel format */
  50. m_data->m_format = fmt;
  51. ivec2 size = GetSize();
  52. int count = size.x * size.y;
  53. /* If we never used this format, allocate a new buffer: we will
  54. * obviously need it. */
  55. if (m_data->m_pixels[(int)fmt] == nullptr)
  56. {
  57. m_data->m_pixels[(int)fmt] = new uint8_t[count * BytesPerPixel(fmt)];
  58. }
  59. /* If the requested format is already the current format, or if the
  60. * current format is invalid, there is nothing to convert. */
  61. if (fmt == old_fmt || old_fmt == PixelFormat::Unknown)
  62. return;
  63. /* Convert pixels */
  64. if (old_fmt == PixelFormat::RGBA_8 && fmt == PixelFormat::RGBA_F32)
  65. {
  66. u8vec4 *src = (u8vec4 *)m_data->m_pixels[(int)old_fmt];
  67. vec4 *dest = (vec4 *)m_data->m_pixels[(int)fmt];
  68. for (int n = 0; n < count; ++n)
  69. dest[n] = u8tof32(src[n]);
  70. }
  71. else if (old_fmt == PixelFormat::RGB_8 && fmt == PixelFormat::RGBA_F32)
  72. {
  73. u8vec3 *src = (u8vec3 *)m_data->m_pixels[(int)old_fmt];
  74. vec4 *dest = (vec4 *)m_data->m_pixels[(int)fmt];
  75. for (int n = 0; n < count; ++n)
  76. dest[n] = u8tof32(u8vec4(src[n], 255));
  77. }
  78. else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::RGBA_8)
  79. {
  80. vec4 *src = (vec4 *)m_data->m_pixels[(int)old_fmt];
  81. u8vec4 *dest = (u8vec4 *)m_data->m_pixels[(int)fmt];
  82. for (int n = 0; n < count; ++n)
  83. dest[n] = f32tou8(src[n]);
  84. #if 0
  85. init_tables();
  86. for (int y = 0; y < size.y; y++)
  87. for (int x = 0; x < size.x; x++)
  88. for (i = 0; i < 4; i++)
  89. {
  90. double p, e;
  91. uint8_t d;
  92. p = src[4 * (y * size.x + x) + i];
  93. if (p < 0.) d = 0.;
  94. else if (p > 1.) d = 255;
  95. else d = (int)(255.999 * pow(p, 1. / global_gamma));
  96. dest[4 * (y * size.x + x) + i] = d;
  97. e = (p - u8tof32(d)) / 16;
  98. if (x < size.x - 1)
  99. src[4 * (y * size.x + x + 1) + i] += e * 7;
  100. if (y < size.y - 1)
  101. {
  102. if (x > 0)
  103. src[4 * ((y + 1) * size.x + x - 1) + i] += e * 3;
  104. src[4 * ((y + 1) * size.x + x) + i] += e * 5;
  105. if (x < size.x - 1)
  106. src[4 * ((y + 1) * size.x + x + 1) + i] += e;
  107. }
  108. }
  109. #endif
  110. }
  111. else if (old_fmt == PixelFormat::Y_F32 && fmt == PixelFormat::RGBA_F32)
  112. {
  113. float *src = (float *)m_data->m_pixels[(int)old_fmt];
  114. vec4 *dest = (vec4 *)m_data->m_pixels[(int)fmt];
  115. for (int n = 0; n < count; ++n)
  116. dest[n] = vec4(vec3(src[n]), 1.0f);
  117. }
  118. else if (old_fmt == PixelFormat::RGBA_F32 && fmt == PixelFormat::Y_F32)
  119. {
  120. vec4 *src = (vec4 *)m_data->m_pixels[(int)old_fmt];
  121. float *dest = (float *)m_data->m_pixels[(int)fmt];
  122. vec3 const coeff(0.299f, 0.587f, 0.114f);
  123. for (int n = 0; n < count; ++n)
  124. dest[n] = dot(coeff, src[n].rgb);
  125. }
  126. else
  127. {
  128. ASSERT(false, "Unable to find proper conversion");
  129. }
  130. }
  131. } /* namespace lol */