Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

205 строки
4.8 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 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://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #if defined __CELLOS_LV2__
  14. #include <cmath>
  15. #include <cell/sysmodule.h>
  16. #include <cell/codec/pngdec.h>
  17. #include "core.h"
  18. #include "../../image/image-private.h"
  19. using namespace std;
  20. namespace lol
  21. {
  22. /*
  23. * Image implementation class
  24. */
  25. DECLARE_IMAGE_LOADER(Ps3ImageData, 100)
  26. {
  27. public:
  28. virtual bool Open(char const *);
  29. virtual bool Close();
  30. virtual void *GetData() const;
  31. private:
  32. static void* Malloc(uint32_t size, void* data) { return malloc(size); };
  33. static int32_t Free(void* ptr, void* data) { free(ptr); return 0; };
  34. uint8_t *pixels;
  35. };
  36. /*
  37. * Public Image class
  38. */
  39. bool Ps3ImageData::Open(char const *path)
  40. {
  41. int32_t err;
  42. /* Initialise decoding library */
  43. CellPngDecMainHandle hmain;
  44. err = cellSysmoduleLoadModule(CELL_SYSMODULE_FS);
  45. if (err != CELL_OK)
  46. {
  47. #if !LOL_RELEASE
  48. Log::Error("could not open Fs sysmodule\n");
  49. #endif
  50. return false;
  51. }
  52. err = cellSysmoduleLoadModule(CELL_SYSMODULE_PNGDEC);
  53. if (err != CELL_OK)
  54. {
  55. #if !LOL_RELEASE
  56. Log::Error("could not open PngDec sysmodule\n");
  57. #endif
  58. return false;
  59. }
  60. CellPngDecThreadInParam in_param;
  61. in_param.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE;
  62. in_param.ppuThreadPriority = 1000;
  63. in_param.spuThreadPriority = 200;
  64. in_param.cbCtrlMallocFunc = Ps3ImageData::Malloc;
  65. in_param.cbCtrlMallocArg = NULL;
  66. in_param.cbCtrlFreeFunc = Ps3ImageData::Free;
  67. in_param.cbCtrlFreeArg = NULL;
  68. CellPngDecThreadOutParam out_param;
  69. err = cellPngDecCreate(&hmain, &in_param, &out_param);
  70. if (err != CELL_OK)
  71. {
  72. #if !LOL_RELEASE
  73. Log::Error("could not create PngDec library\n");
  74. #endif
  75. return false;
  76. }
  77. /* Create decoder */
  78. CellPngDecSubHandle hsub;
  79. char file[1024];
  80. sprintf(file, "/app_home/c:/Users/s.hocevar/le/%s", path);
  81. CellPngDecSrc dec_src;
  82. dec_src.srcSelect = CELL_PNGDEC_FILE;
  83. dec_src.fileName = file;
  84. dec_src.fileOffset = 0;
  85. dec_src.fileSize = 0;
  86. dec_src.streamPtr = NULL;
  87. dec_src.streamSize = 0;
  88. dec_src.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE;
  89. CellPngDecOpnInfo open_info;
  90. err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info);
  91. if (err != CELL_OK)
  92. {
  93. #if !LOL_RELEASE
  94. Log::Error("could not open %s for decoding\n", file);
  95. #endif
  96. return false;
  97. }
  98. CellPngDecInfo info;
  99. err = cellPngDecReadHeader(hmain, hsub, &info);
  100. if (err != CELL_OK)
  101. {
  102. #if !LOL_RELEASE
  103. Log::Error("could not read image header\n");
  104. #endif
  105. return false;
  106. }
  107. CellPngDecInParam in_dec_param;
  108. in_dec_param.commandPtr = NULL;
  109. in_dec_param.outputMode = CELL_PNGDEC_TOP_TO_BOTTOM;
  110. in_dec_param.outputColorSpace = CELL_PNGDEC_RGBA;
  111. in_dec_param.outputBitDepth = 8;
  112. in_dec_param.outputPackFlag = CELL_PNGDEC_1BYTE_PER_1PIXEL;
  113. in_dec_param.outputAlphaSelect = CELL_PNGDEC_STREAM_ALPHA;
  114. in_dec_param.outputColorAlpha = 0xff;
  115. CellPngDecOutParam out_dec_param;
  116. err = cellPngDecSetParameter(hmain, hsub, &in_dec_param, &out_dec_param);
  117. if (err != CELL_OK)
  118. {
  119. #if !LOL_RELEASE
  120. Log::Error("could not configure PngDec decoder\n");
  121. #endif
  122. return false;
  123. }
  124. /* Decode image */
  125. size = ivec2(info.imageWidth, info.imageHeight);
  126. format = Image::FORMAT_RGBA;
  127. pixels = (uint8_t *)malloc(info.imageWidth * 4 * info.imageHeight);
  128. CellPngDecDataCtrlParam data_ctrl_param;
  129. data_ctrl_param.outputBytesPerLine = info.imageWidth * 4;
  130. CellPngDecDataOutInfo data_out_info;
  131. err = cellPngDecDecodeData(hmain, hsub, pixels,
  132. &data_ctrl_param, &data_out_info);
  133. if (err != CELL_OK)
  134. {
  135. #if !LOL_RELEASE
  136. Log::Error("could not run PngDec decoder\n");
  137. #endif
  138. return false;
  139. }
  140. /* Close decoder */
  141. err = cellPngDecClose(hmain, hsub);
  142. if (err != CELL_OK)
  143. {
  144. #if !LOL_RELEASE
  145. Log::Error("could not close PngDec decoder\n");
  146. #endif
  147. return false;
  148. }
  149. /* Deinitialise library */
  150. err = cellPngDecDestroy(hmain);
  151. if (err != CELL_OK)
  152. {
  153. #if !LOL_RELEASE
  154. Log::Error("could not destroy PngDec decoder\n");
  155. #endif
  156. return false;
  157. }
  158. err = cellSysmoduleUnloadModule(CELL_SYSMODULE_PNGDEC);
  159. err = cellSysmoduleUnloadModule(CELL_SYSMODULE_FS);
  160. return true;
  161. }
  162. bool Ps3ImageData::Close()
  163. {
  164. free(pixels);
  165. return true;
  166. }
  167. void * Ps3ImageData::GetData() const
  168. {
  169. return pixels;
  170. }
  171. } /* namespace lol */
  172. #endif /* defined __CELLOS_LV2__ */