home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / libimg / src / ipng.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  7.7 KB  |  262 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "png.h"
  20.  
  21. #include "if.h"
  22. #include "ipng.h"
  23. #define OK 1
  24. #define MINIMUM_DELAY_TIME 10
  25.  
  26.  
  27.  
  28.  
  29. void read_png(il_container *ic, IL_Stream *stream, unsigned int sig_read);
  30.  
  31. void png_get_info(const unsigned char *buf, png_structp png_ptr, png_infop info_ptr);
  32. void  png_read_strm( png_structp png_ptr, png_bytep data, png_size_t length);
  33.  
  34. extern void il_emit_row(il_container *ic, uint8 *buf, uint8 *rgbbuf,
  35.                         int start_column, int len, int row, int row_count,
  36.                         il_draw_mode draw_mode, int ipass);
  37.  
  38. void row_callback( png_structp png_ptr, png_bytep new_row,
  39.    png_uint_32 row_num, int pass /*, il_container *ic*/);
  40.  
  41. extern void end_callback(png_structp png_ptr, png_infop info);
  42. extern void info_callback(png_structp png_ptr, png_infop info);
  43.  
  44. extern void il_create_alpha_mask( il_container *, int, int, int ); 
  45.  
  46.  
  47. extern png_structp png_create_read_struct(png_charp user_png_ver, png_voidp, png_error_ptr, png_error_ptr);
  48. extern png_infop png_create_info_struct(png_structp png_ptr);
  49.  
  50. extern void png_destroy_read_struct(png_structpp, png_infopp, png_infopp);
  51. extern void png_set_progressive_read_fn(png_structp, png_voidp, png_progressive_info_ptr, png_progressive_row_ptr, png_progressive_end_ptr);
  52. extern void png_process_data(png_structp, png_infop, png_bytep, png_size_t);
  53.  
  54.  
  55. /*-----------------------------*/
  56. int
  57. il_png_init(il_container *ic)
  58. {
  59.  
  60.     png_structp read_ptr, write_ptr;
  61.     png_infop read_info_ptr, write_info_ptr, end_info_ptr;
  62.  
  63.     ipng_struct *ipngs;
  64.     NI_ColorSpace *src_color_space = ic->src_header->color_space;
  65.  
  66.     ipngs = XP_NEW_ZAP(ipng_struct);
  67.     if (ipngs) 
  68.     {
  69.         ic->ds = ipngs;
  70.         ipngs->state = PNG_INIT;
  71.         ipngs->ic = ic;
  72.     }
  73.  
  74.     /* Initialize the container's source image header. */
  75.     /* Always decode to 24 bit pixdepth */
  76.  
  77.     src_color_space->type = NI_TrueColor;
  78.     src_color_space->pixmap_depth = 24;
  79.     src_color_space->bit_alloc.index_depth = 0;
  80.     
  81.  
  82.        
  83.     return (ipngs != 0);
  84.  
  85. }
  86.  
  87. /* Gather n characters from the input stream and then enter state s. */
  88.  
  89. int il_png_write(il_container *ic, const unsigned char *buf, int32 len)
  90. {
  91.    ipng_structp ipng_ptr;
  92.  
  93.    png_structp png_ptr;
  94.    png_infop info_ptr;
  95.   
  96.    int status, done;
  97.   
  98.     /*------*/
  99.    
  100.  
  101.     ipng_ptr = (ipng_structp)ic->ds;   
  102.     if(ipng_ptr->state == PNG_INIT ){
  103.         png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
  104.         ipng_ptr->pngs_p = png_ptr;
  105.         /* Allocate/initialize the memory for image information.  REQUIRED. */
  106.         info_ptr = png_create_info_struct(png_ptr);
  107.         ipng_ptr->info_p = info_ptr;
  108.         if (info_ptr == NULL){
  109.               png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
  110.               return !OK;
  111.         }
  112.         png_set_progressive_read_fn(png_ptr, buf,
  113.         info_callback, row_callback, end_callback); 
  114.     }
  115.     else{
  116.         png_ptr = ipng_ptr->pngs_p;
  117.         info_ptr = ipng_ptr->info_p;
  118.     }
  119.     /* note addition of ic to png structure.... */
  120.     png_ptr->io_ptr = ic;
  121.     png_process_data( png_ptr, info_ptr, buf, len );
  122.         
  123.     ipng_ptr->state = PNG_CONTINUE;
  124.    
  125.     return OK;
  126. }
  127.  
  128. void
  129. png_set_dims( il_container *ic, png_structp png_ptr)
  130. {    
  131.     int status;
  132.  
  133.     NI_PixmapHeader *img_hdr = &ic->image->header;                  
  134.     NI_PixmapHeader *src_hdr = ic->src_header;
  135.  
  136.     src_hdr->width = img_hdr->width = png_ptr->width;
  137.     src_hdr->height = img_hdr->height = png_ptr->height;
  138.  
  139.     if((png_ptr->channels > 3 )||(png_ptr->trans)){
  140.         il_create_alpha_mask( png_ptr->io_ptr, 0, png_ptr->width, png_ptr->height);
  141.         ic->image->header.is_interleaved_alpha = TRUE;
  142.         il_init_image_transparent_pixel(ic);
  143.  
  144.     }
  145.  
  146.     status = il_size(ic);
  147.  
  148.     /*Note: all png's are decoded to RGB or RGBa and
  149.     converted by imglib to appropriate pixdepth*/
  150.  
  151.     il_setup_color_space_converter(ic);
  152.     
  153.     return;
  154. }
  155.  
  156. il_png_init_transparency(png_structp png_ptr, il_container *ic, int index)
  157. {
  158.     IL_IRGB *src_trans_pixel /*= ic->src_header->transparent_pixel*/;
  159.     IL_IRGB *img_trans_pixel;
  160.     
  161.     if (ic->src_header) {
  162.         ic->src_header->transparent_pixel = XP_NEW_ZAP(IL_IRGB);
  163.     }
  164.     src_trans_pixel = ic->src_header->transparent_pixel;
  165.  
  166.         /* Initialize the destination image's transparent pixel. */
  167.     il_init_image_transparent_pixel(ic);
  168.  
  169.         /* Set the source image's transparent pixel color to be the preferred
  170.            transparency color of the destination image. */
  171.         img_trans_pixel = ic->image->header.transparent_pixel;
  172.  
  173.         src_trans_pixel->red = png_ptr->trans_values.red;
  174.         src_trans_pixel->green = png_ptr->trans_values.green;
  175.         src_trans_pixel->blue = png_ptr->trans_values.blue;
  176.   
  177. /* 
  178.         src_trans_pixel->red = img_trans_pixel->red;
  179.         src_trans_pixel->green = img_trans_pixel->green;
  180.         src_trans_pixel->blue = img_trans_pixel->blue;
  181.   */
  182.         
  183.     /* Set the source image's transparent pixel index.  Do this even if the source
  184.        image's transparent pixel has previously been set, since the index can vary
  185.        from frame to frame in an animated gif. */
  186.     src_trans_pixel->index = index;
  187.  
  188.     return TRUE;
  189. }
  190.  
  191.  
  192. static void
  193. il_png_destroy_transparency(il_container *ic)
  194. {
  195.     NI_PixmapHeader *src_header = ic->src_header;
  196.     
  197.     if (src_header->transparent_pixel) {
  198.         /* Destroy the source image's transparent pixel. */
  199.         XP_FREE(src_header->transparent_pixel);
  200.         src_header->transparent_pixel = NULL;
  201.  
  202.         /* Destroy the destination image's transparent pixel. */
  203.         il_destroy_image_transparent_pixel(ic);
  204.     }
  205. }
  206.  
  207.  
  208. static void
  209. png_delay_time_callback(void *closure)
  210. {
  211.     ipng_struct *ipng_ptr = (ipng_struct *)closure;
  212.  
  213.     XP_ASSERT(ipng_ptr->state == PNG_DELAY);
  214.  
  215.     ipng_ptr->delay_time = NULL;
  216.  
  217.     if (ipng_ptr->ic->state == IC_ABORT_PENDING)
  218.         return;                                        
  219.  
  220.     ipng_ptr->delay_time = 0;         /* Reset for next image */
  221.  
  222.     
  223. }
  224.  
  225. void il_png_complete(il_container *ic)
  226. {
  227.     ipng_structp ipng_ptr;
  228.  
  229.     ipng_ptr = ic->ds;
  230.  
  231.     il_png_abort(ic);
  232.    
  233.     /* notify observers that the current frame has completed. */
  234.  
  235.     il_frame_complete_notify(ic);                
  236.  
  237.     /* An image can specify a delay time before which to display
  238.        subsequent images.  Block until the appointed time. */
  239.     if(ipng_ptr->delay_time < MINIMUM_DELAY_TIME )
  240.         ipng_ptr->delay_time = MINIMUM_DELAY_TIME ;
  241.     if (ipng_ptr->delay_time){
  242.             ipng_ptr->delay_timeout =
  243.             FE_SetTimeout(png_delay_time_callback, ipng_ptr, ipng_ptr->delay_time);
  244.  
  245.             /* Essentially, tell the decoder state machine to wait
  246.             forever.  The delay_time callback routine will wake up the
  247.             state machine and force it to decode the next image. */
  248.             ipng_ptr->state = PNG_DELAY;
  249.      } else {
  250.             ipng_ptr->state = PNG_INIT;
  251.      }
  252.  
  253.     return;
  254. }
  255.  
  256. void il_png_abort(il_container *ic)
  257. {
  258. /*    il_abort( ic ); */
  259.     return;
  260. }
  261.  
  262.