Exemplo n.º 1
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;
}
KDuint8* xmReadTileETC ( KDFile* file, XMImage* image )
{
	ETCDecode*		decode = (ETCDecode*) image->decode;

	KDuint8*		pixels		= 0;
	KDint			block_size	= 0; 
	KDint32			tile_size   = 0;

	if ( decode->pixels )
	{
		kdFree ( decode->pixels );
		decode->pixels = 0;
	}

	block_size = 8;

	tile_size = ( ( image->ptr_tile->width + 3 ) / 4 ) * ( ( image->ptr_tile->height + 3 ) / 4 ) * block_size;

	pixels = (KDuint8*) kdMalloc ( tile_size );
	if ( !pixels )
	{
		goto cleanup;
	}

	if ( kdFread ( pixels, tile_size, 1, file ) == 0 )
	{			
		//goto cleanup;
	}

	if ( decode->uncomp == 1 )
	{
		tile_size = image->ptr_tile->width * image->ptr_tile->height * 3;
		decode->pixels = (KDuint8*) kdMalloc ( tile_size );

		if ( decode->pixels )
		{
			etc1_decode_image ( pixels, decode->pixels, image->ptr_tile->width, image->ptr_tile->height, 3, image->ptr_tile->width * 3 );
		}

		kdFree ( pixels );
	}
	else
	{
		decode->pixels = pixels;
		image->ptr_tile->size = tile_size;
	}

	decode->row_count = 0;
	image->ptr_tile->stride = tile_size / image->ptr_tile->height;

	return decode->pixels;

cleanup :

	if ( pixels )
	{
		kdFree ( pixels );
	}

	return 0;
}