From a8af3108a411d417c92d45a721dd4bd68701e830 Mon Sep 17 00:00:00 2001 From: "pnunn%netscape.com" Date: Thu, 22 Apr 1999 22:37:16 +0000 Subject: [PATCH] Implements decoder api. pnunn. --- modules/libimg/src/if.cpp | 359 ++++++++++++++++++++++++++++---------- 1 file changed, 268 insertions(+), 91 deletions(-) diff --git a/modules/libimg/src/if.cpp b/modules/libimg/src/if.cpp index cba56cb2b855..30b09a530dfc 100644 --- a/modules/libimg/src/if.cpp +++ b/modules/libimg/src/if.cpp @@ -20,18 +20,21 @@ * if.c --- Top-level image library routines */ - #include "if.h" #include "merrors.h" -#ifdef STANDALONE_IMAGE_LIB + +#include "nsIImgDecoder.h" +#include "nsImgDCallbk.h" #include "xpcompat.h" -#else -#include "xpgetstr.h" -#endif /* STANDALONE_IMAGE_LIB */ + +#include "nsImgDecCID.h" +#include "prtypes.h" + #include "il_strm.h" + PR_BEGIN_EXTERN_C extern int XP_MSG_IMAGE_PIXELS; extern int MK_UNABLE_TO_LOCATE_FILE; @@ -51,6 +54,185 @@ int il_debug=0; static IL_GroupContext *il_global_img_cx_list = NULL; +/*-------------------------------------------------*/ +class ImgDecoder : public nsIImgDecoder { + +public: + + NS_DECL_ISUPPORTS + + il_container *GetContainer() {return mContainer;}; + il_container *SetContainer(il_container *ic) {mContainer=ic; return ic;}; + + ImgDecoder(il_container *aContainer){mContainer=aContainer;}; + ~ImgDecoder(); + +private: + il_container* mContainer; +}; + +NS_IMETHODIMP ImgDecoder::AddRef() +{ + NS_INIT_REFCNT(); + return NS_OK; +} + +NS_IMETHODIMP ImgDecoder::Release() +{ + return NS_OK; +} + +NS_IMETHODIMP ImgDecoder::QueryInterface(const nsIID& aIID, void** aResult) +{ + if (NULL == aResult) { + return NS_ERROR_NULL_POINTER; + } + + if (aIID.Equals(kImgDecoderIID)) { + *aResult = (void*) this; + NS_INIT_REFCNT(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + +/*-----------------------------------------*/ +/*-----------------------------------------*/ +NS_IMETHODIMP ImgDCallbk::ImgDCBSetupColorspaceConverter() +{ + if( mContainer != NULL ) { + il_setup_color_space_converter(mContainer); + } + return 0; +} + +NI_ColorSpace* +ImgDCallbk::ImgDCBCreateGreyScaleColorSpace() +{ + if( mContainer != NULL ) { + return IL_CreateGreyScaleColorSpace(1,1); + } + return 0; +} + +NS_IMETHODIMP ImgDCallbk::ImgDCBResetPalette() +{ + if( mContainer != NULL ) { + il_reset_palette(mContainer); + } + return NS_OK; +} + + +NS_IMETHODIMP +ImgDCallbk::ImgDCBHaveHdr(int destwidth, int destheight) +{ + if( mContainer != NULL ) { + il_dimensions_notify(mContainer, destwidth, destheight); + } + return 0; + +} + +NS_IMETHODIMP +ImgDCallbk::ImgDCBInitTransparentPixel() +{ + if( mContainer != NULL ) { + il_init_image_transparent_pixel(mContainer); + } + return 0; + +} + +NS_IMETHODIMP +ImgDCallbk::ImgDCBDestroyTransparentPixel() +{ + if( mContainer != NULL ) { + il_destroy_image_transparent_pixel(mContainer); + } + return 0; + +} + +NS_IMETHODIMP +ImgDCallbk :: ImgDCBHaveRow(uint8 *rowbuf, uint8* rgbrow, + int x_offset, int len, + int row, int dup_rowcnt, + uint8 draw_mode, + int pass ) +{ + if( mContainer != NULL ) { + + il_emit_row(mContainer, rowbuf, rgbrow, x_offset, len, + row, dup_rowcnt, (il_draw_mode)draw_mode, pass ); + } + return 0; + +} + +NS_IMETHODIMP +ImgDCallbk :: ImgDCBHaveImageFrame() +{ + if( mContainer != NULL ) { + il_frame_complete_notify(mContainer); + } + return 0; +} + +NS_IMETHODIMP +ImgDCallbk::ImgDCBFlushImage() +{ + if( mContainer != NULL ) { + il_flush_image_data(mContainer); + } + return 0; +} + +NS_IMETHODIMP +ImgDCallbk:: ImgDCBImageSize() +{ + if( mContainer != NULL ) { + il_size(mContainer); + } + return 0; +} + +NS_IMETHODIMP +ImgDCallbk :: ImgDCBHaveImageAll() +{ + if( mContainer != NULL ) { + il_image_complete(mContainer); + } + return 0; + +} + +NS_IMETHODIMP +ImgDCallbk :: ImgDCBError() +{ + if( mContainer != NULL ) { + } + return 0; + +} + +void* +ImgDCallbk :: ImgDCBSetTimeout(TimeoutCallbackFunction func, void* closure, uint32 msecs) +{ + return( IL_SetTimeout(func, closure, msecs )); + +} + +NS_IMETHODIMP +ImgDCallbk :: ImgDCBClearTimeout(void *timer_id) +{ + IL_ClearTimeout(timer_id); + return 0; +} + +/*-------------------------------------------------*/ +ImgDecoder *imgdec; /*********************** Image Observer Notification. ************************* * * These functions are used to send messages to registered observers of an @@ -174,7 +356,7 @@ il_image_complete_notify(il_container *ic) &message_data); } } - +#if 1 /* Notify observers that a frame of an image animation has finished decoding. */ void @@ -194,7 +376,33 @@ il_frame_complete_notify(il_container *ic) &message_data); } } +#endif +int +il_compute_percentage_complete(int row, il_container *ic) +{ + uint percent_height; + int percent_done = 0; + + percent_height = (uint)(row * (uint32)100 / ic->image->header.height); + switch(ic->pass) { + case 0: percent_done = percent_height; /* non-interlaced GIF */ + break; + case 1: percent_done = percent_height / 8; + break; + case 2: percent_done = 12 + percent_height / 8; + break; + case 3: percent_done = 25 + percent_height / 4; + break; + case 4: percent_done = 50 + percent_height / 2; + break; + default: + ILTRACE(0,("Illegal interlace pass")); + break; + } + + return percent_done; +} /* Notify observers of image progress. */ void @@ -228,7 +436,7 @@ il_progress_notify(il_container *ic) /* Interlaced GIFs are weird */ if (ic->type == IL_GIF) { - percent_done = il_gif_compute_percentage_complete(row, ic); + percent_done = il_compute_percentage_complete(row, ic); } else { @@ -593,7 +801,7 @@ il_size(il_container *ic) ic->sized = 1; /* Notify observers of the target dimensions of the image. */ - il_dimensions_notify(ic, ic->dest_width, ic->dest_height); + ic->imgdcb->ImgDCBHaveHdr(ic->dest_width, ic->dest_height); /* Fabricate a title for the image and notify observers. Image Plugins will need to supply information on the image type. */ @@ -696,8 +904,9 @@ IL_StreamWriteReady(il_container *ic) { uint request_size = 1; - if (ic->write_ready) - request_size = (*ic->write_ready)(ic); + if (ic->imgdec) + // request_size = (*ic->write_ready)(); + request_size = ((ic->imgdec->ImgDWriteReady))(); if (!request_size) return 0; @@ -787,7 +996,7 @@ IL_Type(const char *buf, int32 len) int IL_StreamWrite(il_container *ic, const unsigned char *str, int32 len) { - int err = 0; + unsigned int err = 0; ILTRACE(4, ("il: write with %5d bytes for %s\n", len, ic->url_address)); @@ -806,9 +1015,14 @@ IL_StreamWrite(il_container *ic, const unsigned char *str, int32 len) ic->bytes_consumed += len; if (len) - err = (*ic->write)(ic, (unsigned char *)str, len); - /* Notify observers of image progress. */ + // err = (*ic->write)(ic, (unsigned char *)str, len); + + err = (ic->imgdec->ImgDWrite)(str, len); + + + + /* Notify observers of image progress. */ il_progress_notify(ic); if (err < 0) @@ -821,7 +1035,7 @@ IL_StreamWrite(il_container *ic, const unsigned char *str, int32 len) int IL_StreamFirstWrite(il_container *ic, const unsigned char *str, int32 len) { - int (*init)(il_container *); + int ret =0; PR_ASSERT(ic); PR_ASSERT(ic->image); @@ -847,62 +1061,53 @@ IL_StreamFirstWrite(il_container *ic, const unsigned char *str, int32 len) /* Figure out the image type, possibly overriding the given MIME type */ ic->type = il_type(ic->type, (const char*) str, len); - ic->write_ready = NULL; + /* Grab the URL's expiration date */ + nsresult result; + if (ic->url) ic->expires = ic->url->GetExpires(); - switch (ic->type) - { - case IL_GIF: - init = il_gif_init; - ic->write = il_gif_write; - ic->complete = il_gif_complete; - ic->write_ready = il_gif_write_ready; - ic->abort = il_gif_abort; - break; - case IL_XBM: - init = il_xbm_init; - ic->write = il_xbm_write; - ic->abort = il_xbm_abort; - ic->complete = il_xbm_complete; - break; + ImgDecoder *imgdec; - case IL_JPEG: - init = il_jpeg_init; - ic->write = il_jpeg_write; - ic->abort = il_jpeg_abort; - ic->complete = il_jpeg_complete; - break; + char imgtype[150]; + char imgtypestr[200]; - case IL_PNG: - init = il_png_init; - ic->write = il_png_write; - ic->abort = il_png_abort; - ic->complete = il_png_complete; - break; + switch (ic->type) { + case IL_GIF : PL_strcpy(imgtype, "gif"); break; + case IL_XBM : PL_strcpy(imgtype, "xbm"); break; + case IL_JPEG : PL_strcpy(imgtype, "jpeg"); break; + case IL_PNG : PL_strcpy(imgtype, "png"); break; + default : PL_strcpy(imgtype, ""); + } + sprintf(imgtypestr, "component://netscape/image/decoder&type=image/%s" + , imgtype ); + + result = nsRepository::CreateInstance(imgtypestr, + NULL, + kImgDecoderIID, + (void **)&imgdec); - case IL_NOTFOUND: - ILTRACE(1,("il: html image")); - return MK_IMAGE_LOSSAGE; - - default: - ILTRACE(1,("il: ignoring unknown image type (%d)", ic->type)); - return MK_IMAGE_LOSSAGE; - } - - if (!(*init)(ic)) - { - ILTRACE(0,("il: image init failed")); - return MK_OUT_OF_MEMORY; - } - + if (NS_FAILED(result)) + return MK_IMAGE_LOSSAGE; + + + imgdec->SetContainer(ic); + ic->imgdec = imgdec; + ret = imgdec->ImgDInit(); + if(ret == 0) + { + ILTRACE(0,("il: image init failed")); + return MK_OUT_OF_MEMORY; + } + return 0; } + /* Called when a container is aborted by Netlib. */ static void il_container_aborted(il_container *ic) @@ -1060,8 +1265,8 @@ IL_NetRequestDone(il_container *ic, ilIURL *url, int status) void il_image_abort(il_container *ic) { - if (ic->abort) - (*ic->abort)(ic); + if (ic->imgdec) + ic->imgdec->ImgDAbort(); /* Clear any pending timeouts */ if (ic->row_output_timeout) { @@ -1090,8 +1295,8 @@ IL_StreamComplete(il_container *ic, PRBool is_multipart) ic->is_multipart = is_multipart; - if (ic->complete) - (*ic->complete)(ic); + if (ic->imgdec) + ic->imgdec->ImgDComplete(); else il_image_complete(ic); } @@ -1690,6 +1895,7 @@ IL_GetImage(const char* image_url, int is_internal_external_reconnect = FALSE; #endif /* STANDALONE_IMAGE_LIB */ int is_view_image; + int is_internal_external_reconnect = FALSE; /* Create a new instance for this image request. */ image_req = PR_NEWZAP(IL_ImageReq); @@ -1779,6 +1985,7 @@ IL_GetImage(const char* image_url, #endif /* M12N */ #else is_view_image = FALSE; + #endif /* STANDALONE_IMAGE_LIB */ if (!il_add_client(img_cx, ic, image_req, is_view_image)) @@ -2319,38 +2526,8 @@ IL_GetNaturalDimensions(IL_ImageReq *image_req, int *width, int *height) } } -#ifndef STANDALONE_IMAGE_LIB -#ifndef M12N /* XXXM12N Get rid of these functions */ -void -IL_DisableScaling(MWContext *cx) -{ - il_process *ip; - - if (!cx) - return; - - if (!(ip=cx->imageProcess)) - return; - - ip->dontscale = 1; -} -void -IL_DisableLowSrc(MWContext *cx) -{ - il_process *ip; - - if (!cx) - return; - - if (!(ip=cx->imageProcess)) - return; - - ip->nolowsrc = 1; -} -#endif /* M12N */ -#endif /* STANDALONE_IMAGE_LIB */ #ifdef PROFILE #pragma profile off #endif