KDbool Image::initWithImageData ( const KDubyte* pData, KDint32 nDataLen )
{
	KDbool	bRet = false;

	do
	{
		CC_BREAK_IF ( !pData || nDataLen <= 0 );

		KDubyte*	pUnpackedData = nullptr;
		KDint		nUnpackedLen = 0;

		// detecgt and unzip the compress file
		if ( ZipUtils::isCCZBuffer ( pData, nDataLen ) )
		{
			nUnpackedLen = ZipUtils::inflateCCZBuffer ( pData, nDataLen, &pUnpackedData );
		}
		else if ( ZipUtils::isGZipBuffer ( pData, nDataLen ) )
		{
			nUnpackedLen = ZipUtils::inflateMemory ( const_cast<KDubyte*> ( pData ), nDataLen, &pUnpackedData );
		}
		else
		{
			pUnpackedData = const_cast<KDubyte*> ( pData );
			nUnpackedLen = nDataLen;
		}

		KDFile*		pFile   = kdFmemopen ( pUnpackedData, nUnpackedLen, "rb" );
		KDoff		uOffset = kdFtell ( pFile );
		KDImageATX	pImage  = KD_NULL;

		do 
		{
			Texture2D::PixelFormat  eFormat = Texture2D::getDefaultAlphaPixelFormat ( );
			
			if ( eFormat == Texture2D::PixelFormat::AUTO )
			{			
				pImage = kdGetImageInfoFromStreamATX ( pFile );
				CC_BREAK_IF ( !pImage );

				KDint  nFormat = kdGetImageIntATX ( pImage, KD_IMAGE_FORMAT_ATX );
				KDint  nBpp    = kdGetImageIntATX ( pImage, KD_IMAGE_BITSPERPIXEL_ATX );
				KDint  nAlpha  = kdGetImageIntATX ( pImage, KD_IMAGE_ALPHA_ATX );
				KDint  nType   = kdGetImageIntATX ( pImage, KD_IMAGE_TYPE );

				m_eFileType = (Format) nType;
		
				kdFreeImageATX ( pImage );
				kdFseek ( pFile, uOffset, KD_SEEK_SET );

				switch ( nFormat )
				{
					case KD_IMAGE_FORMAT_COMPRESSED_ATX :	
						if ( ( nType == KD_IMAGE_TYPE_PVR   && !Configuration::getInstance ( )->supportsPVRTC ( ) ) ||
							 ( nType == KD_IMAGE_TYPE_S3TC  && !Configuration::getInstance ( )->supportsS3TC  ( ) ) ||
							 ( nType == KD_IMAGE_TYPE_ATITC && !Configuration::getInstance ( )->supportsATITC ( ) ) ||
							 ( nType == KD_IMAGE_TYPE_ETC   && !Configuration::getInstance ( )->supportsETC   ( ) ) )
						{
							eFormat = Texture2D::PixelFormat::RGBA8888;
						}
						else
						{
							eFormat = Texture2D::PixelFormat::COMPRESSED;
						}
						break;

					case KD_IMAGE_FORMAT_ALPHA8_ATX:
						eFormat = Texture2D::PixelFormat::A8;
						break;

					case KD_IMAGE_FORMAT_LUMINANCE_ATX:
						eFormat = Texture2D::PixelFormat::I8;
						break;

					case KD_IMAGE_FORMAT_LUMALPHA_ATX:
						eFormat = Texture2D::PixelFormat::AI88;
						break;

					case KD_IMAGE_FORMAT_PALETTED_ATX:
						eFormat = Texture2D::PixelFormat::RGB5A1;
						break;

					case KD_IMAGE_FORMAT_RGB_ATX:
						if ( nBpp == 24 || nBpp == 48 )
						{
							eFormat = Texture2D::PixelFormat::RGB888;
						}
						else
						{
							eFormat = Texture2D::PixelFormat::RGB565;
						}						
						break;

					case KD_IMAGE_FORMAT_RGBA_ATX:
						if ( nBpp == 16 )
						{
							eFormat = ( nAlpha == 4 ) ? Texture2D::PixelFormat::RGBA4444 : Texture2D::PixelFormat::RGB5A1;
						}
						else
						{
							eFormat = Texture2D::PixelFormat::RGBA8888;
						}
						break;

					default:
						break; break;
				}
			}
	
			pImage = kdGetImageFromStreamATX ( pFile, (KDint) eFormat, KD_IMAGE_FLAG_PREMULTIPLIED_ALPHA );
			CC_BREAK_IF ( !pImage );
			
			m_eRenderFormat				= (Texture2D::PixelFormat) kdGetImageIntATX ( pImage, KD_IMAGE_FORMAT_ATX );
			m_nWidth					= kdGetImageIntATX ( pImage, KD_IMAGE_WIDTH_ATX );
			m_nHeight					= kdGetImageIntATX ( pImage, KD_IMAGE_HEIGHT_ATX );
			m_bHasPremultipliedAlpha	= kdGetImageIntATX ( pImage, KD_IMAGE_FLAG_PREMULTIPLIED_ALPHA ) ? KD_TRUE : KD_FALSE;
			m_nDataLen					= kdGetImageIntATX ( pImage, KD_IMAGE_DATASIZE_ATX );
			m_nNumberOfMipmaps			= kdGetImageIntATX ( pImage, KD_IMAGE_LEVELS_ATX );
			m_pData						= (KDubyte*) kdGetImagePointerATX ( pImage, KD_IMAGE_POINTER_BUFFER_ATX );
			m_pImageAtx					= pImage;

			for ( KDint i = 0; i < m_nNumberOfMipmaps; i++ )
			{
				m_aMipmaps [ i ].address = m_pData + kdGetImageLevelIntATX ( pImage, KD_IMAGE_BUFFEROFFSET_ATX, i );
				m_aMipmaps [ i ].len     = kdGetImageLevelIntATX ( pImage, KD_IMAGE_DATASIZE_ATX, i );
			}

			bRet = true;

		} while ( 0 );

		if ( pFile )
		{
			kdFclose ( pFile );
		}
	
		if ( pUnpackedData != pData )
		{
			kdFree ( pUnpackedData );
		}

	} while ( 0 );

	return bRet;
}
Example #2
0
KD_API KDImageATX KD_APIENTRY kdGetImageFromStreamATX(KDFile *file, KDint format, KDint flags)
{
    _KDImageATX *image = (_KDImageATX *)kdMalloc(sizeof(_KDImageATX));
    if(image == KD_NULL)
    {
        kdSetError(KD_ENOMEM);
        return KD_NULL;
    }
    image->levels = 0;
    image->bpp = 8;

    KDStat st;
    if(kdFstat(file, &st) == -1)
    {
        kdFree(image);
        kdSetError(KD_EIO);
        return KD_NULL;
    }

    void *filedata = kdMalloc((KDsize)st.st_size);
    if(filedata == KD_NULL)
    {
        kdFree(image);
        kdSetError(KD_ENOMEM);
        return KD_NULL;
    }
    if(kdFread(filedata, 1, (KDsize)st.st_size, file) != (KDsize)st.st_size)
    {
        kdFree(filedata);
        kdFree(image);
        kdSetError(KD_EIO);
        return KD_NULL;
    }
    if(kdFseek(file, 0, KD_SEEK_SET) == -1)
    {
        kdFree(filedata);
        kdFree(image);
        kdSetError(KD_EIO);
        return KD_NULL;
    }

    KDint channels = 0;
    image->format = format;
    switch(image->format)
    {
        case(KD_IMAGE_FORMAT_RGBA8888_ATX):
        {
            channels = 4;
            image->alpha = KD_TRUE;
            break;
        }
        case(KD_IMAGE_FORMAT_RGB888_ATX):
        {
            channels = 3;
            image->alpha = KD_FALSE;
            break;
        }
        case(KD_IMAGE_FORMAT_LUMALPHA88_ATX):
        {
            channels = 2;
            image->alpha = KD_TRUE;
            break;
        }
        case(KD_IMAGE_FORMAT_LUM8_ATX):
        {
            channels = 1;
            image->alpha = KD_FALSE;
            break;
        }
        case(KD_IMAGE_FORMAT_COMPRESSED_ATX):
        {
            /* TODO: Load compressed formats (do not decode) */
        }
        default:
        {
            kdFree(filedata);
            kdFree(image);
            kdSetError(KD_EINVAL);
            return KD_NULL;
        }
    }

    if(kdStrstrVEN(file->pathname, ".pvr"))
    {
        if(channels == 4)
        {
            /* PVR v2 only*/
            struct PVR_Texture_Header {
                KDuint dwHeaderSize;      /* size of the structure */
                KDuint dwHeight;          /* height of surface to be created */
                KDuint dwWidth;           /* width of input surface */
                KDuint dwMipMapCount;     /* number of mip-map levels requested */
                KDuint dwpfFlags;         /* pixel format flags */
                KDuint dwTextureDataSize; /* Total size in bytes */
                KDuint dwBitCount;        /* number of bits per pixel  */
                KDuint dwRBitMask;        /* mask for red bit */
                KDuint dwGBitMask;        /* mask for green bits */
                KDuint dwBBitMask;        /* mask for blue bits */
                KDuint dwAlphaBitMask;    /* mask for alpha channel */
                KDuint dwPVR;             /* magic number identifying pvr file */
                KDuint dwNumSurfs;        /* the number of surfaces present in the pvr */
            };
            struct PVR_Texture_Header header;
            kdMemcpy(&header, filedata, sizeof(KDuint) * 13);

            image->height = (KDint)header.dwHeight;
            image->width = (KDint)header.dwWidth;
            image->size = (KDsize)image->width * (KDsize)image->height * (KDsize)channels * sizeof(KDuint);
            image->buffer = kdMalloc(image->size);
            /* PVRCT2/4 RGB/RGBA compressed formats for now */
            __kdDecompressPVRTC((const KDuint8 *)filedata + header.dwHeaderSize, 0, image->width, image->height, image->buffer);
        }
    }
    else
    {
        if(flags == KD_IMAGE_FLAG_FLIP_X_ATX)
        {
            stbi_set_flip_vertically_on_load(1);
        }
        image->buffer = stbi_load_from_memory(filedata, (KDint)st.st_size, &image->width, &image->height, (KDint[]) {0}, channels);
        image->size = (KDsize)image->width * (KDsize)image->height * (KDsize)channels * sizeof(KDuint);
    }

    kdFree(filedata);
    if(image->buffer == KD_NULL)
    {
        kdLogMessagefKHR("%s.\n", stbi_failure_reason());
        kdFree(image);
        kdSetError(KD_EILSEQ);
        return KD_NULL;
    }
    return image;
}