Skip to content

Commit 17eaa7a

Browse files
author
Walzer
committed
issue cocos2d#161,support *.jpg
1 parent 9df42b7 commit 17eaa7a

File tree

7 files changed

+172
-48
lines changed

7 files changed

+172
-48
lines changed

cocos2dx/cocos2dx-uphone.vcproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<Tool
4141
Name="VCCLCompilerTool"
4242
Optimization="0"
43-
AdditionalIncludeDirectories="..\..\PRJ_TG3\Include\ThirdParty\iconv;..\..\PRJ_TG3\Include\ThirdParty\zlib;..\..\PRJ_TG3\Include\ThirdParty\libpng;..\..\PRJ_TG3\Include\ThirdParty\libxml2;.\include;.\Res;..\..\PRJ_TG3\Include;..\..\PRJ_TG3\Include\MTAPI;..\..\PRJ_TG3\Include\OpenGL;..\..\PRJ_TG3\Include\TCOM;..\..\PRJ_TG3\TG3\Include;..\..\PRJ_TG3\TG3\TG3_Implement;..\..\PRJ_TG3\EOS_SYS;..\..\PRJ_TG3\Common\SoftSupport;..\..\PRJ_TG3\Common\ICU\Include;.\"
43+
AdditionalIncludeDirectories="..\..\PRJ_TG3\Include\ThirdParty\iconv;..\..\PRJ_TG3\Include\ThirdParty\zlib;..\..\PRJ_TG3\Include\ThirdParty\libpng;..\..\PRJ_TG3\Include\ThirdParty\libjpeg;..\..\PRJ_TG3\Include\ThirdParty\libxml2;.\include;.\Res;..\..\PRJ_TG3\Include;..\..\PRJ_TG3\Include\MTAPI;..\..\PRJ_TG3\Include\OpenGL;..\..\PRJ_TG3\Include\TCOM;..\..\PRJ_TG3\TG3\Include;..\..\PRJ_TG3\TG3\TG3_Implement;..\..\PRJ_TG3\EOS_SYS;..\..\PRJ_TG3\Common\SoftSupport;..\..\PRJ_TG3\Common\ICU\Include;.\"
4444
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_TRANZDA_VM_;SS_MAKEDLL;__TG3_PURE_DLL__;_USE_MATH_DEFINES"
4545
MinimalRebuild="true"
4646
BasicRuntimeChecks="3"
@@ -64,7 +64,7 @@
6464
/>
6565
<Tool
6666
Name="VCLinkerTool"
67-
AdditionalDependencies="WS2_32.Lib EosConfig.lib SoftSupport.lib TG3_DLL.lib libEGL.lib libTG3_EGL.lib libgles_cm.lib libxml2.lib zlib.lib libpng14-imp.lib ImageToolKit_d.lib"
67+
AdditionalDependencies="WS2_32.Lib EosConfig.lib SoftSupport.lib TG3_DLL.lib libEGL.lib libTG3_EGL.lib libgles_cm.lib libxml2.lib zlib.lib libpng14-imp.lib ImageToolKit_d.lib libjpeg.lib"
6868
OutputFile="$(OutDir)/libcocos2d.dll"
6969
LinkIncremental="2"
7070
AdditionalLibraryDirectories="../../PRJ_TG3/Common/ICU/lib;../../PRJ_TG3/Mtapi/Win32/lib;../../PRJ_TG3/LIB/Win32Lib;../../PRJ_TG3/Common/SoftSupport"

cocos2dx/include/CCRenderTexture.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ THE SOFTWARE.
2828
#include "CCSprite.h"
2929

3030
namespace cocos2d {
31-
enum
31+
enum tImageFormat
3232
{
3333
kImageFormatJPG = 0,
3434
kImageFormatPNG = 1

cocos2dx/include/CCTexture2D.h

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ typedef enum {
4545
kCCTexture2DPixelFormat_Automatic = 0,
4646
//! 32-bit texture: RGBA8888
4747
kCCTexture2DPixelFormat_RGBA8888,
48+
//! 24-bit texture: RGBA888
49+
kCCTexture2DPixelFormat_RGB888,
4850
//! 16-bit texture: used with images that have alpha pre-multiplied
4951
kCCTexture2DPixelFormat_RGB565,
5052
//! 8-bit textures used as masks
@@ -60,6 +62,7 @@ typedef enum {
6062
// backward compatibility stuff
6163
kTexture2DPixelFormat_Automatic = kCCTexture2DPixelFormat_Automatic,
6264
kTexture2DPixelFormat_RGBA8888 = kCCTexture2DPixelFormat_RGBA8888,
65+
kTexture2DPixelFormat_RGB888 = kCCTexture2DPixelFormat_RGB888,
6366
kTexture2DPixelFormat_RGB565 = kCCTexture2DPixelFormat_RGB565,
6467
kTexture2DPixelFormat_A8 = kCCTexture2DPixelFormat_A8,
6568
kTexture2DPixelFormat_RGBA4444 = kCCTexture2DPixelFormat_RGBA4444,

cocos2dx/platform/uphone/CCXUIImage_uphone.cpp

+103-20
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ THE SOFTWARE.
2727
//#include <ImageToolKit/IT_ImageLoader.h>
2828
#include <TG3.h>
2929
#include "png.h"
30+
#include "jpeglib.h"
3031

3132
//using namespace ImageToolKit;
3233
using namespace std;
@@ -39,6 +40,7 @@ typedef struct
3940
int offset;
4041
}tImageSource;
4142

43+
4244
// because we do not want to include "png.h" in CCXUIImage_uphone.h, so we implement
4345
// the function as a static function
4446
static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
@@ -78,10 +80,10 @@ UIImage::UIImage(TBitmap *bitmap)
7880
m_imageInfo.data = m_pBitmap->GetDataPtr();
7981
m_imageInfo.height = m_pBitmap->GetHeight();
8082
m_imageInfo.width = m_pBitmap->GetWidth();
81-
m_imageInfo.hasAlpha = m_pBitmap->HasAlphaData();
83+
m_imageInfo.hasAlpha = true;//m_pBitmap->HasAlphaData();
8284
// uphone only support predefined
8385
m_imageInfo.isPremultipliedAlpha = true;
84-
m_imageInfo.bitsPerComponent = m_pBitmap->GetDepth();
86+
m_imageInfo.bitsPerComponent = m_pBitmap->GetDepth() / 4;
8587
}
8688
}
8789

@@ -107,10 +109,26 @@ UIImage::~UIImage(void)
107109
}
108110
}
109111

110-
bool UIImage::initWithContentsOfFile(const string &strPath)
112+
bool UIImage::initWithContentsOfFile(const string &strPath, tImageFormat imageType)
111113
{
112-
// use libpng load image
113-
return loadPng(strPath.c_str());
114+
bool bRet = false;
115+
116+
switch (imageType)
117+
{
118+
case kImageFormatPNG:
119+
// use libpng load image
120+
bRet = loadPng(strPath.c_str());
121+
break;
122+
case kImageFormatJPG:
123+
bRet = loadJpg(strPath.c_str());
124+
break;
125+
default:
126+
// unsupported image type
127+
bRet = false;
128+
break;
129+
}
130+
131+
return bRet;
114132
}
115133

116134
unsigned int UIImage::width(void)
@@ -141,21 +159,14 @@ int UIImage::CGImageGetBitsPerComponent(void)
141159
return m_imageInfo.bitsPerComponent;
142160
}
143161

144-
// 0 -> it is a mask
145-
// 1 -> other
162+
// now we only support RGBA8888 or RGB888
163+
// so it has color space
146164
int UIImage::CGImageGetColorSpace(void)
147165
{
148-
int nRet = 1;
149-
150-
if (m_imageInfo.bitsPerComponent == 8)
151-
{
152-
nRet = 0;
153-
}
154-
155-
return nRet;
166+
return 1;
156167
}
157168

158-
unsigned char* UIImage::getRGBA8888Data(void)
169+
unsigned char* UIImage::getData(void)
159170
{
160171
return m_imageInfo.data;
161172
}
@@ -263,10 +274,7 @@ bool UIImage::loadPngFromStream(unsigned char *data, int nLength)
263274
m_imageInfo.height = info_ptr->height;
264275
m_imageInfo.width = info_ptr->width;
265276
m_imageInfo.isPremultipliedAlpha = false;
266-
// we use CCX_RGA or CCX_RGB to save data
267-
// so the bitsPerComponet is 32, and it also
268-
// has the alpha data
269-
m_imageInfo.bitsPerComponent = 32;
277+
m_imageInfo.bitsPerComponent = info_ptr->bit_depth;
270278
m_imageInfo.hasAlpha = true;
271279

272280
// convert to appropriate format, we now only support RGBA8888
@@ -324,6 +332,81 @@ bool UIImage::loadPngFromStream(unsigned char *data, int nLength)
324332
return true;
325333
}
326334

335+
bool UIImage::loadJpg(const char *strFileName)
336+
{
337+
/* these are standard libjpeg structures for reading(decompression) */
338+
struct jpeg_decompress_struct cinfo;
339+
struct jpeg_error_mgr jerr;
340+
/* libjpeg data structure for storing one row, that is, scanline of an image */
341+
JSAMPROW row_pointer[1];
342+
343+
FILE *infile = fopen( strFileName, "rb" );
344+
unsigned long location = 0;
345+
int i = 0;
346+
347+
if ( !infile )
348+
{
349+
return false;
350+
}
351+
/*jpeg_stdio_src(&cinfo, infile);*/
352+
353+
/* here we set up the standard libjpeg error handler */
354+
cinfo.err = jpeg_std_error( &jerr );
355+
356+
/* setup decompression process and source, then read JPEG header */
357+
jpeg_create_decompress( &cinfo );
358+
359+
/* this makes the library read from infile */
360+
jpeg_stdio_src( &cinfo, infile );
361+
362+
/* reading the image header which contains image information */
363+
jpeg_read_header( &cinfo, true );
364+
365+
// we only support RGB or grayscale
366+
if (cinfo.jpeg_color_space != JCS_RGB)
367+
{
368+
if (cinfo.jpeg_color_space == JCS_GRAYSCALE || cinfo.jpeg_color_space == JCS_YCbCr)
369+
{
370+
cinfo.out_color_space = JCS_RGB;
371+
}
372+
}
373+
else
374+
{
375+
return false;
376+
}
377+
378+
/* Start decompression jpeg here */
379+
jpeg_start_decompress( &cinfo );
380+
381+
/* init image info */
382+
m_imageInfo.width = cinfo.image_width;
383+
m_imageInfo.height = cinfo.image_height;
384+
m_imageInfo.hasAlpha = false;
385+
m_imageInfo.isPremultipliedAlpha = false;
386+
m_imageInfo.bitsPerComponent = 8;
387+
m_imageInfo.data = new unsigned char[cinfo.output_width*cinfo.output_height*cinfo.output_components];
388+
389+
/* now actually read the jpeg into the raw buffer */
390+
/*row_pointer[0] = (unsigned char *)malloc( cinfo.output_width*cinfo.num_components );*/
391+
row_pointer[0] = new unsigned char[cinfo.output_width*cinfo.output_components];
392+
393+
/* read one scan line at a time */
394+
while( cinfo.output_scanline < cinfo.image_height )
395+
{
396+
jpeg_read_scanlines( &cinfo, row_pointer, 1 );
397+
for( i=0; i<cinfo.image_width*cinfo.num_components;i++)
398+
m_imageInfo.data[location++] = row_pointer[0][i];
399+
}
400+
401+
/* wrap up decompression, destroy objects, free pointers and close open files */
402+
jpeg_finish_decompress( &cinfo );
403+
jpeg_destroy_decompress( &cinfo );
404+
delete row_pointer[0];
405+
fclose( infile );
406+
407+
return true;
408+
}
409+
327410
bool UIImage::save(const std::string &strFileName, int nFormat)
328411
{
329412
/// @todo uiimage::save

cocos2dx/platform/uphone/CCXUIImage_uphone.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@ THE SOFTWARE.
2727

2828
#include <string>
2929
#include "ccxCommon.h"
30+
#include "CCRenderTexture.h"
3031

3132
class TBitmap;
3233
namespace cocos2d {
3334

34-
typedef struct
35+
// typedef enum {
36+
// kImageTypePNG = 0,
37+
// kImageTypeJPG = 1,
38+
// } CCXImageType;
39+
40+
typedef struct
3541
{
3642
unsigned int height;
3743
unsigned int width;
@@ -50,7 +56,7 @@ class CCX_DLL UIImage
5056
UIImage(int nX, int nY, void *buffer);
5157
~UIImage(void);
5258

53-
bool initWithContentsOfFile(const std::string &strPath);
59+
bool initWithContentsOfFile(const std::string &strPath, tImageFormat imageType = kImageFormatPNG);
5460
bool initWithData(unsigned char *pBuffer, int nLength);
5561
bool initWithBuffer(int tx, int ty, unsigned char *pBuffer);
5662
// bool initWithCGImage(CGImageRef pCGImage);
@@ -67,11 +73,12 @@ class CCX_DLL UIImage
6773
int CGImageGetColorSpace(void);
6874

6975
// convert the bitmap to 256 pixel format, and every component is 8 bits
70-
unsigned char* getRGBA8888Data(void);
76+
unsigned char* getData(void);
7177

7278
private:
7379
bool loadPng(const char* strFileName);
7480
bool loadPngFromStream(unsigned char *data, int nLength);
81+
bool loadJpg(const char *strFileName);
7582

7683
private:
7784
TBitmap *m_pBitmap;

cocos2dx/textures/CCTexture2D.cpp

+39-5
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ bool CCTexture2D::initWithData(const void *data, CCTexture2DPixelFormat pixelFor
144144
case kCCTexture2DPixelFormat_RGBA8888:
145145
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixelsWide, pixelsHigh, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
146146
break;
147+
case kCCTexture2DPixelFormat_RGB888:
148+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pixelsWide, pixelsHigh, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
149+
break;
147150
case kCCTexture2DPixelFormat_RGBA4444:
148151
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixelsWide, pixelsHigh, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
149152
break;
@@ -238,12 +241,21 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
238241

239242
if(colorSpace)
240243
{
241-
if(hasAlpha || bpp >= 8)
244+
if(hasAlpha)
245+
{
242246
pixelFormat = defaultAlphaPixelFormat();
247+
}
243248
else
244249
{
245-
CCLOG("cocos2d: CCTexture2D: Using RGB565 texture since image has no alpha");
246-
pixelFormat = kCCTexture2DPixelFormat_RGB565;
250+
if (bpp >= 8)
251+
{
252+
pixelFormat = kCCTexture2DPixelFormat_RGB888;
253+
}
254+
else
255+
{
256+
CCLOG("cocos2d: CCTexture2D: Using RGB565 texture since image has no alpha");
257+
pixelFormat = kCCTexture2DPixelFormat_RGB565;
258+
}
247259
}
248260
}
249261
else
@@ -279,7 +291,7 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
279291
// info = kCGImageAlphaOnly;
280292
// context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide, NULL, info);
281293

282-
tempData = (void*)(image->getRGBA8888Data());
294+
tempData = (void*)(image->getData());
283295
NSAssert(tempData != NULL, "NULL image data.");
284296
if(image->width() == POTWide && image->height() == POTHigh)
285297
{
@@ -299,7 +311,29 @@ bool CCTexture2D::initPremultipliedATextureWithImage(UIImage *image, unsigned in
299311
memcpy(pTargetData+POTWide*4*y, pPixelData+(image->width())*4*y, (image->width())*4);
300312
}
301313
}
302-
break;
314+
break;
315+
case kCCTexture2DPixelFormat_RGB888:
316+
tempData = (void*)(image->getData());
317+
NSAssert(tempData != NULL, "NULL image data.");
318+
if(image->width() == POTWide && image->height() == POTHigh)
319+
{
320+
data = new UINT8[POTHigh * POTWide * 3];
321+
memcpy(data, tempData, POTHigh * POTWide * 3);
322+
}
323+
else
324+
{
325+
data = new UINT8[POTHigh * POTWide * 3];
326+
memset(data, 0, POTHigh * POTWide * 3);
327+
328+
UINT8* pPixelData = (UINT8*) tempData;
329+
UINT8* pTargetData = (UINT8*) data;
330+
331+
for(unsigned int y=0; y<image->height(); ++y)
332+
{
333+
memcpy(pTargetData+POTWide*3*y, pPixelData+(image->width())*3*y, (image->width())*3);
334+
}
335+
}
336+
break;
303337
default:
304338
NSAssert(0, "Invalid pixel format");
305339
//[NSException raise:NSInternalInconsistencyException format:@"Invalid pixel format"];

cocos2dx/textures/CCTextureCache.cpp

+14-17
Original file line numberDiff line numberDiff line change
@@ -202,22 +202,19 @@ CCTexture2D * CCTextureCache::addImage(const char * path)
202202
#endif
203203
}
204204
// Issue #886: TEMPORARY FIX FOR TRANSPARENT JPEGS IN IOS4
205-
// else if ( lowerCase.find(".jpg") || lowerCase(".jpeg") )
206-
// {
207-
// // convert jpg to png before loading the texture
208-
// UIImage *jpg = [[UIImage alloc] initWithContentsOfFile:fullpath];
209-
// UIImage *png = [[UIImage alloc] initWithData:UIImagePNGRepresentation(jpg)];
210-
// tex = [ [CCTexture2D alloc] initWithImage: png ];
211-
// [png release];
212-
// [jpg release];
213-
//
214-
// if( tex )
215-
// [textures setObject: tex forKey:path];
216-
// else
217-
// CCLOG(@"cocos2d: Couldn't add image:%@ in CCTextureCache", path);
218-
//
219-
// [tex release];
220-
// }
205+
else
206+
if (std::string::npos != lowerCase.find(".jpg") || std::string::npos != lowerCase.find(".jpeg"))
207+
{
208+
UIImage * image = new UIImage();
209+
if(! image->initWithContentsOfFile(fullpath, kImageFormatJPG))
210+
{
211+
delete image;
212+
return NULL;
213+
}
214+
texture = new CCTexture2D();
215+
texture->initWithImage(image);
216+
CCX_SAFE_DELETE(image);// image->release();
217+
}
221218
else
222219
{
223220
//# work around for issue #910
@@ -227,7 +224,7 @@ CCTexture2D * CCTextureCache::addImage(const char * path)
227224
#else
228225
// prevents overloading the autorelease pool
229226
UIImage * image = new UIImage();
230-
if(! image->initWithContentsOfFile(fullpath))
227+
if(! image->initWithContentsOfFile(fullpath, kImageFormatPNG))
231228
{
232229
delete image;
233230
return NULL;

0 commit comments

Comments
 (0)