source: trunk/src/image/codec/ps3-image.cpp @ 2506

Last change on this file since 2506 was 2506, checked in by sam, 7 years ago

base: start removing occurrences of NULL on our long journey to nullptr.

  • Property svn:keywords set to Id
File size: 5.0 KB
Line 
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
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#if defined __CELLOS_LV2__
16
17#include <cell/sysmodule.h>
18#include <cell/codec/pngdec.h>
19
20#include "core.h"
21#include "../../image/image-private.h"
22
23using namespace std;
24
25namespace lol
26{
27
28/*
29 * Image implementation class
30 */
31
32DECLARE_IMAGE_LOADER(Ps3ImageData, 100)
33{
34public:
35    virtual bool Open(char const *);
36    virtual bool Close();
37
38    virtual void *GetData() const;
39
40private:
41    static void* Malloc(uint32_t size, void* data) { return malloc(size); };
42    static int32_t Free(void* ptr, void* data) { free(ptr); return 0; };
43    uint8_t *pixels;
44};
45
46/*
47 * Public Image class
48 */
49
50bool Ps3ImageData::Open(char const *path)
51{
52    int32_t err;
53
54    /* Initialise decoding library */
55    CellPngDecMainHandle hmain;
56
57    err = cellSysmoduleLoadModule(CELL_SYSMODULE_FS);
58    if (err != CELL_OK)
59    {
60#if !LOL_RELEASE
61        Log::Error("could not open Fs sysmodule\n");
62#endif
63        return false;
64    }
65
66    err = cellSysmoduleLoadModule(CELL_SYSMODULE_PNGDEC);
67    if (err != CELL_OK)
68    {
69#if !LOL_RELEASE
70        Log::Error("could not open PngDec sysmodule\n");
71#endif
72        return false;
73    }
74
75    CellPngDecThreadInParam in_param;
76    in_param.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE;
77    in_param.ppuThreadPriority = 1000;
78    in_param.spuThreadPriority = 200;
79    in_param.cbCtrlMallocFunc = Ps3ImageData::Malloc;
80    in_param.cbCtrlMallocArg = nullptr;
81    in_param.cbCtrlFreeFunc = Ps3ImageData::Free;
82    in_param.cbCtrlFreeArg = nullptr;
83    CellPngDecThreadOutParam out_param;
84    err = cellPngDecCreate(&hmain, &in_param, &out_param);
85    if (err != CELL_OK)
86    {
87#if !LOL_RELEASE
88        Log::Error("could not create PngDec library\n");
89#endif
90        return false;
91    }
92
93    /* Create decoder */
94    CellPngDecSrc dec_src;
95    dec_src.srcSelect = CELL_PNGDEC_FILE;
96    dec_src.fileOffset = 0;
97    dec_src.fileSize = 0;
98    dec_src.streamPtr = nullptr;
99    dec_src.streamSize = 0;
100    dec_src.spuThreadEnable  = CELL_PNGDEC_SPU_THREAD_ENABLE;
101    CellPngDecSubHandle hsub;
102    CellPngDecOpnInfo open_info;
103
104    Array<String> pathlist = System::GetPathList(path);
105    for (int i = 0; i < pathlist.Count(); ++i)
106    {
107        dec_src.fileName = (String("/app_home") + pathlist[i]).C();
108        err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info);
109        if (err == CELL_OK)
110            break;
111    }
112
113    if (err != CELL_OK)
114    {
115#if !LOL_RELEASE
116        Log::Error("could not open %s for decoding\n", path);
117#endif
118        return false;
119    }
120
121    CellPngDecInfo info;
122    err = cellPngDecReadHeader(hmain, hsub, &info);
123    if (err != CELL_OK)
124    {
125#if !LOL_RELEASE
126        Log::Error("could not read image header in %s\n", path);
127#endif
128        return false;
129    }
130
131    CellPngDecInParam in_dec_param;
132    in_dec_param.commandPtr = nullptr;
133    in_dec_param.outputMode = CELL_PNGDEC_TOP_TO_BOTTOM;
134    in_dec_param.outputColorSpace = CELL_PNGDEC_RGBA;
135    in_dec_param.outputBitDepth = 8;
136    in_dec_param.outputPackFlag = CELL_PNGDEC_1BYTE_PER_1PIXEL;
137    in_dec_param.outputAlphaSelect = CELL_PNGDEC_STREAM_ALPHA;
138    in_dec_param.outputColorAlpha = 0xff;
139    CellPngDecOutParam out_dec_param;
140    err = cellPngDecSetParameter(hmain, hsub, &in_dec_param, &out_dec_param);
141    if (err != CELL_OK)
142    {
143#if !LOL_RELEASE
144        Log::Error("could not configure PngDec decoder\n");
145#endif
146        return false;
147    }
148
149    /* Decode image */
150    size = ivec2(info.imageWidth, info.imageHeight);
151    format = Image::FORMAT_RGBA;
152    pixels = (uint8_t *)malloc(info.imageWidth * 4 * info.imageHeight);
153    CellPngDecDataCtrlParam data_ctrl_param;
154    data_ctrl_param.outputBytesPerLine = info.imageWidth * 4;
155    CellPngDecDataOutInfo data_out_info;
156    err = cellPngDecDecodeData(hmain, hsub, pixels,
157                               &data_ctrl_param, &data_out_info);
158    if (err != CELL_OK)
159    {
160#if !LOL_RELEASE
161        Log::Error("could not run PngDec decoder on %s\n", path);
162#endif
163        return false;
164    }
165
166    /* Close decoder */
167    err = cellPngDecClose(hmain, hsub);
168    if (err != CELL_OK)
169    {
170#if !LOL_RELEASE
171        Log::Error("could not close PngDec decoder\n");
172#endif
173        return false;
174    }
175
176    /* Deinitialise library */
177    err = cellPngDecDestroy(hmain);
178    if (err != CELL_OK)
179    {
180#if !LOL_RELEASE
181        Log::Error("could not destroy PngDec decoder\n");
182#endif
183        return false;
184    }
185    err = cellSysmoduleUnloadModule(CELL_SYSMODULE_PNGDEC);
186    err = cellSysmoduleUnloadModule(CELL_SYSMODULE_FS);
187
188    return true;
189}
190
191bool Ps3ImageData::Close()
192{
193    free(pixels);
194
195    return true;
196}
197
198void * Ps3ImageData::GetData() const
199{
200    return pixels;
201}
202
203} /* namespace lol */
204
205#endif /* defined __CELLOS_LV2__ */
206
Note: See TracBrowser for help on using the repository browser.