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; }