You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

197 lines
5.1 KiB

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