GF_Err gf_img_file_dec(char *png_filename, u32 *hint_oti, u32 *width, u32 *height, u32 *pixel_format, char **dst, u32 *dst_size) { u32 fsize, read, oti; FILE *f; char *data; GF_Err e; f = gf_f64_open(png_filename, "rb"); if (!f) return GF_URL_ERROR; oti = 0; if (!hint_oti || ! *hint_oti) { char *ext = strrchr(png_filename, '.'); if (!ext) return GF_NOT_SUPPORTED; if (!stricmp(ext, ".png")) oti = GPAC_OTI_IMAGE_PNG; else if (!stricmp(ext, ".jpg") || !stricmp(ext, ".jpeg")) oti = GPAC_OTI_IMAGE_JPEG; } gf_f64_seek(f, 0, SEEK_END); fsize = (u32)gf_f64_tell(f); gf_f64_seek(f, 0, SEEK_SET); data = gf_malloc(fsize); read = fread(data, sizeof(char), fsize, f); fclose( f ); if (read != fsize) return GF_IO_ERR; e = GF_NOT_SUPPORTED; *dst_size = 0; if (oti == GPAC_OTI_IMAGE_JPEG) { #ifdef GPAC_HAS_JPEG e = gf_img_jpeg_dec(data, fsize, width, height, pixel_format, NULL, dst_size, 0); if (*dst_size) { *dst = gf_malloc(*dst_size); return gf_img_jpeg_dec(data, fsize, width, height, pixel_format, NULL, dst_size, 0); } #endif } else if (oti == GPAC_OTI_IMAGE_PNG) { #ifdef GPAC_HAS_PNG e = gf_img_png_dec(data, fsize, width, height, pixel_format, NULL, dst_size); if (*dst_size) { *dst = gf_malloc(*dst_size); return gf_img_png_dec(data, fsize, width, height, pixel_format, *dst, dst_size); } #endif } return e; }
static GF_Err PNG_ProcessData(GF_MediaDecoder *ifcg, char *inBuffer, u32 inBufferLength, u16 ES_ID, u32 *CTS, char *outBuffer, u32 *outBufferLength, u8 PaddingBits, u32 mmlevel) { #ifndef GPAC_DISABLE_AV_PARSERS GF_Err e; PNGCTX(); e = gf_img_png_dec(inBuffer, inBufferLength, &ctx->width, &ctx->height, &ctx->pixel_format, outBuffer, outBufferLength); switch (ctx->pixel_format) { case GF_PIXEL_GREYSCALE: ctx->BPP = 1; break; case GF_PIXEL_ALPHAGREY: ctx->BPP = 2; break; case GF_PIXEL_RGB_24: ctx->BPP = 3; if (ctx->aux_type==3) ctx->pixel_format = GF_PIXEL_RGBS; break; case GF_PIXEL_RGBA: case GF_PIXEL_RGBD: ctx->BPP = 4; if (ctx->aux_type==1) ctx->pixel_format = GF_PIXEL_RGBD; else if (ctx->aux_type==2) ctx->pixel_format = GF_PIXEL_RGBDS; else if (ctx->aux_type==3) ctx->pixel_format = GF_PIXEL_RGBAS; break; } ctx->out_size = *outBufferLength; return e; #else return GF_NOT_SUPPORTED; #endif //GPAC_DISABLE_AV_PARSERS }
static void imagetexture_update(GF_TextureHandler *txh) { if (gf_node_get_tag(txh->owner)!=TAG_MPEG4_CacheTexture) { MFURL url = ((M_ImageTexture *) txh->owner)->url; /*setup texture if needed*/ if (!txh->is_open && url.count) { gf_sc_texture_play(txh, &url); } gf_sc_texture_update_frame(txh, 0); if ( /*URL is present but not opened - redraw till fetch*/ /* (txh->stream && !txh->tx_io) && */ /*image has been updated*/ txh->needs_refresh) { /*mark all subtrees using this image as dirty*/ gf_node_dirty_parents(txh->owner); gf_sc_invalidate(txh->compositor, NULL); } return; } /*cache texture case*/ else { M_CacheTexture *ct = (M_CacheTexture *) txh->owner; /*decode cacheTexture data */ if ((ct->data || ct->image.buffer) && !txh->data) { #ifndef GPAC_DISABLE_AV_PARSERS u32 out_size; GF_Err e; /*BT/XMT playback: load to memory*/ if (ct->image.buffer) { char *par = (char *) gf_scene_get_service_url( gf_node_get_graph(txh->owner ) ); char *src_url = gf_url_concatenate(par, ct->image.buffer); FILE *test = gf_fopen( src_url ? src_url : ct->image.buffer, "rb"); if (test) { fseek(test, 0, SEEK_END); ct->data_len = (u32) gf_ftell(test); ct->data = gf_malloc(sizeof(char)*ct->data_len); fseek(test, 0, SEEK_SET); if (ct->data_len != fread(ct->data, 1, ct->data_len, test)) { GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to load CacheTexture data from file %s: IO err\n", src_url ? src_url : ct->image.buffer ) ); gf_free(ct->data); ct->data = NULL; ct->data_len = 0; } gf_fclose(test); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to load CacheTexture data from file %s: not found\n", src_url ? src_url : ct->image.buffer ) ); } ct->image.buffer = NULL; if (src_url) gf_free(src_url); } /*BIFS decoded playback*/ switch (ct->objectTypeIndication) { case GPAC_OTI_IMAGE_JPEG: out_size = 0; e = gf_img_jpeg_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size, 3); if (e==GF_BUFFER_TOO_SMALL) { u32 BPP; txh->data = gf_malloc(sizeof(char) * out_size); if (txh->pixelformat==GF_PIXEL_GREYSCALE) BPP = 1; else BPP = 3; e = gf_img_jpeg_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size, BPP); if (e==GF_OK) { gf_sc_texture_allocate(txh); gf_sc_texture_set_data(txh); txh->needs_refresh = 1; txh->stride = out_size / txh->height; } } break; case GPAC_OTI_IMAGE_PNG: out_size = 0; e = gf_img_png_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size); if (e==GF_BUFFER_TOO_SMALL) { txh->data = gf_malloc(sizeof(char) * out_size); e = gf_img_png_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size); if (e==GF_OK) { gf_sc_texture_allocate(txh); gf_sc_texture_set_data(txh); txh->needs_refresh = 1; txh->stride = out_size / txh->height; } } break; } #endif // GPAC_DISABLE_AV_PARSERS /*cacheURL is specified, store the image*/ if (ct->cacheURL.buffer) { u32 i; u8 hash[20]; FILE *cached_texture; char szExtractName[GF_MAX_PATH], section[64], *opt, *src_url; opt = (char *) gf_cfg_get_key(txh->compositor->user->config, "General", "CacheDirectory"); if (opt) { strcpy(szExtractName, opt); } else { opt = gf_get_default_cache_directory(); strcpy(szExtractName, opt); gf_free(opt); } strcat(szExtractName, "/"); src_url = (char *) gf_scene_get_service_url( gf_node_get_graph(txh->owner ) ); gf_sha1_csum((u8 *)src_url, (u32) strlen(src_url), hash); for (i=0; i<20; i++) { char t[3]; t[2] = 0; sprintf(t, "%02X", hash[i]); strcat(szExtractName, t); } strcat(szExtractName, "_"); strcat(szExtractName, ct->cacheURL.buffer); cached_texture = gf_fopen(szExtractName, "wb"); if (cached_texture) { gf_fwrite(ct->data, 1, ct->data_len, cached_texture); gf_fclose(cached_texture); } /*and write cache info*/ if (ct->expirationDate!=0) { sprintf(section, "@cache=%p", ct); gf_cfg_set_key(txh->compositor->user->config, section, "serviceURL", src_url); gf_cfg_set_key(txh->compositor->user->config, section, "cacheFile", szExtractName); gf_cfg_set_key(txh->compositor->user->config, section, "cacheName", ct->cacheURL.buffer); if (ct->expirationDate>0) { char exp[50]; u32 sec, frac; gf_net_get_ntp(&sec, &frac); sec += ct->expirationDate; sprintf(exp, "%u", sec); gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", exp); } else { gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", "0"); } } } /*done with image, destroy buffer*/ if (ct->data) gf_free(ct->data); ct->data = NULL; ct->data_len = 0; } } }