home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libcnv / libcnv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.3 KB  |  331 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.  
  20. #include "xp_core.h" //used to make library compile faster on win32 do not ifdef this or it wont work
  21.  
  22. #include <memory.h>
  23. #include <stdio.h>
  24. #include <malloc.h>
  25.  
  26. #include "xp_core.h"/*defines of int32 ect*/
  27. #include "xpassert.h"
  28. #include "xp_mcom.h"/*XP_STRDUP command*/
  29. #include "ntypes.h" /*for mwcontext for callback routines*/
  30.  
  31. #include "libcnv.h"
  32. #include "readbmp.h"
  33. #include "writejpg.h"
  34. //#include "writepng.h"
  35. /*the following 4 includes are for the color quantization wrapper to colorqnt.h*/
  36. #include "pbmplus.h"
  37. #include "ppm.h"
  38. #include "ppmcmap.h"
  39. #include "colorqnt.h"
  40.  
  41.  
  42.  
  43. /*accepts a stream of bytes that will be read in and converted to a JPEG/GIF FILE
  44. jpeg/gif file (default to p_output default) stream that is returned 
  45. : you are responsible for free'ing the returned memory*/
  46. typedef void * LPVOID;
  47.  
  48. CONVERT_IMG_INFO *create_img_info();
  49. void copy_img_info(CONVERT_IMG_INFO *p_dest,CONVERT_IMG_INFO *p_origin);
  50. void destroy_img_info(CONVERT_IMG_INFO *p_info);
  51.  
  52. void clean_convert_img_array(CONVERT_IMG_ARRAY array,int16 count);
  53.  
  54. /*PUBLIC API*/
  55. convimgenum
  56. select_file_type (CONVERT_IMGCONTEXT * p_input)
  57. {
  58.   int16 c;
  59.   if ((c = getc(p_input->m_stream.m_file)) == EOF)
  60.     return conv_unknown;
  61.   if (ungetc(c, p_input->m_stream.m_file) == EOF)
  62.     return conv_unknown;
  63.  
  64.   switch (c) {
  65.   case 'B':
  66.     p_input->m_imagetype=conv_bmp;
  67.     return conv_bmp;
  68.   default:
  69.     p_input->m_imagetype=conv_unknown; 
  70.     return conv_unknown;
  71.     break;
  72.   }
  73.  
  74.   return conv_unknown;            /* suppress compiler warnings */
  75. }
  76.  
  77. /*PUBLIC API*/
  78. CONVERT_IMAGERESULT 
  79. convert_quantize_pixels(CONVERT_IMG_ARRAY imagearray,int16 imagewidth,int16 imageheight,int16 maxcolorvalue)
  80. {
  81.   /*wrapper for colorqnt.cpp we just want to change the pixels, we dont need any info*/
  82.   CONVERT_IMAGERESULT t_result;
  83.   int16 t_dummycolors;
  84.   colorhist_vector t_dummyvector;
  85.   t_result=quantize_colors(imagearray,imagewidth,imageheight,&maxcolorvalue,&t_dummycolors,&t_dummyvector);
  86.   if ( t_dummyvector == (colorhist_vector) 0 )
  87.     return t_result;
  88.   ppm_freecolorhist( t_dummyvector );
  89.   return t_result;
  90. }
  91.  
  92. CONVERT_IMG_INFO *create_img_info()
  93. {
  94.   return calloc (1,sizeof(CONVERT_IMG_INFO));
  95. }
  96.  
  97. void destroy_img_info(CONVERT_IMG_INFO *p_info)
  98. {
  99.   if (p_info)
  100.   {
  101.     if (p_info->m_colormap)
  102.       free(p_info->m_colormap);
  103.     free (p_info);
  104.   }
  105. }
  106.  
  107. void copy_img_info(CONVERT_IMG_INFO *p_dest,CONVERT_IMG_INFO *p_origin)
  108. {
  109.   XP_ASSERT(p_dest);
  110.   XP_ASSERT(p_origin);
  111.   memcpy(p_dest,p_origin,sizeof(CONVERT_IMG_INFO));/*shallow copy!!*/
  112. }
  113.  
  114. /*PUBLIC API*/
  115. CONVERT_IMAGERESULT convert_stream2image(CONVERT_IMGCONTEXT p_input,CONVERT_IMG_INFO *p_imageinfo,int16 p_numoutputs,char **p_outputfilenames) /*0== OK <0 == user cancel >0 == error*/
  116. {
  117.   CONVERT_IMGCONTEXT *t_outputparams;
  118.   CONVERT_IMG_INFO *t_imageinfo=NULL;
  119.   CONVERT_IMG_ARRAY t_rowarray=NULL;
  120.   convimgenum t_outputtype;
  121.   CONVERT_IMAGERESULT t_err;
  122.   int16 i;
  123.   XP_ASSERT(p_imageinfo);
  124.   if ((!p_numoutputs)||(!p_imageinfo))
  125.     return CONVERR_INVALIDDEST;
  126.   if ((conv_unknown==p_input.m_imagetype)&&(CONVERT_MEMORY==p_input.m_stream.m_type)) /*dont know what it is and its not a file!*/
  127.     return CONVERR_INVALIDSOURCE;/*reading unknown stream??*/
  128.   t_outputparams=calloc(p_numoutputs,sizeof(CONVERT_IMGCONTEXT));
  129.   if (!t_outputparams)
  130.     return CONVERR_OUTOFMEMORY;
  131.   else if ((conv_unknown==p_input.m_imagetype)&&(CONVERT_FILE==p_input.m_stream.m_type))
  132.   {
  133.     /*read in header info*/
  134.     if (conv_unknown==select_file_type(&p_input))
  135.       return CONVERR_INVALIDSOURCE;/*read file header and tell me what kind it is. also fill info into p_input*/
  136.   }
  137.   t_imageinfo=create_img_info();
  138.   if (conv_bmp==p_input.m_imagetype) /*bitmap*/
  139.   {
  140.     t_err=start_input_bmp(t_imageinfo,&p_input);
  141.     if (t_err==CONV_OK)
  142.     {
  143. #if 0
  144.       if (t_imageinfo->m_bitsperpixel<=8)/*256Colors GIF  ..check colorspace*/
  145.         t_outputtype=conv_png;
  146.       else /* >8 means use JPEG*/
  147. #endif /*no png support for composer yet*/
  148.         t_outputtype=conv_jpeg;
  149.       for (i=0;i<p_numoutputs;i++)/*need to set defaults for outputs*/
  150.       {
  151.         t_outputparams[i].m_imagetype=t_outputtype;
  152.         t_outputparams[i].m_callbacks=p_input.m_callbacks;
  153.       }
  154.       t_err==finish_input_bmp(t_imageinfo,&p_input,&t_rowarray);
  155.       if (t_err!=CONV_OK)
  156.       {
  157.         clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  158.         destroy_img_info(t_imageinfo);
  159.         return t_err;
  160.       }
  161.     }
  162.     else
  163.     {
  164.       destroy_img_info(t_imageinfo);
  165.       return t_err;
  166.     }
  167.   }
  168.   /*PICT CRAP HERE AS WELL AS XPM*/
  169.   else
  170.   {
  171.     destroy_img_info(t_imageinfo);
  172.     return CONVERR_INVALIDSOURCE;
  173.   }
  174.   /*callback: this must give us the information on how to convert the image. in case of JPEG, give us the same as parse_switches in the JPEG libraries
  175.   they can change t_defaultoutput if they must and change t_imageinfo for default values i.e. color quantization*/
  176.   if (!p_input.m_callbacks.m_dialogimagecallback)
  177.   {
  178.     clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  179.     destroy_img_info(t_imageinfo);
  180.     return CONV_CANCEL;
  181.   }
  182.   t_err=(*p_input.m_callbacks.m_dialogimagecallback)(&p_input,t_outputparams,t_imageinfo,p_numoutputs,t_rowarray);
  183.   if (CONV_OK!=t_err)
  184.   {
  185.     clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  186.     destroy_img_info(t_imageinfo);
  187.     return t_err;
  188.   }
  189.   for (i=0;i<p_numoutputs;i++)
  190.   {
  191.     if (t_outputparams[i].m_stream.m_type!=CONVERT_FILE)
  192.     {
  193.       /* And we're done! */
  194.       clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  195.       destroy_img_info(t_imageinfo);
  196.       return t_err;
  197.     }
  198.     //copying strings to p_outputfilenames[i]
  199.     if (p_outputfilenames)
  200.       p_outputfilenames[i]=XP_STRDUP(t_outputparams[i].m_filename);
  201.     switch(t_outputparams[i].m_imagetype)
  202.     {
  203.     case conv_jpeg:
  204.       {
  205.         t_err=write_JPEG_file(t_rowarray,&t_outputparams[i],t_imageinfo,p_input.m_callbacks);
  206.         if (t_err!=CONV_OK)
  207.         {
  208.           /* And we're done! */
  209.           clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  210.           destroy_img_info(t_imageinfo);
  211.           return t_err;
  212.         }
  213.       }
  214.       break;
  215. #if 0
  216.     case conv_png:
  217.       {
  218.         /*color quantization*/
  219.         t_err=write_PNG_file(t_rowarray,&(t_outputparams[i]),t_imageinfo,p_input.m_callbacks);
  220.         if (t_err!=CONV_OK)
  221.         {
  222.           /* And we're done! */
  223.           clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  224.           destroy_img_info(t_imageinfo);
  225.           return t_err;
  226.         }
  227.       }
  228.       break;
  229. #endif //no png support for composer yet
  230.     case conv_plugin: /*plugin*/
  231.       {
  232.         /* to be safe we will clear colormap out out p_outputinfos*/
  233.         clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  234.         copy_img_info(p_imageinfo,t_imageinfo);/*shallow copy! no colormap*/
  235.         destroy_img_info(t_imageinfo);/*the color map is destroyed here */
  236.         return CONV_OK; /*get rid of compiler warnings*/
  237.       }
  238.       break;
  239.     default:
  240.       {
  241.         /* to be safe we will clear colormap out out p_outputinfos*/
  242.         clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  243.         copy_img_info(p_imageinfo,t_imageinfo);/*shallow copy! no colormap*/
  244.         destroy_img_info(t_imageinfo);/*the color map is destroyed here */
  245.         return CONVERR_INVALIDDEST;
  246.       }
  247.       break;
  248.     }
  249.   }
  250.   /* to be safe we will clear colormap out out p_outputinfos*/
  251.   clean_convert_img_array(t_rowarray,t_imageinfo->m_image_height);
  252.   copy_img_info(p_imageinfo,t_imageinfo);/*shallow copy! no colormap*/
  253.   destroy_img_info(t_imageinfo);/*the color map is destroyed here */
  254.   if (p_input.m_callbacks.m_completecallback) //its OK to be null
  255.     t_err=(*p_input.m_callbacks.m_completecallback)(t_outputparams,p_numoutputs,p_input.m_pMWContext);
  256.   else 
  257.     t_err=CONV_OK;
  258.   return t_err;
  259. }
  260.  
  261.  
  262.  
  263. /*
  264. this clean function assumes the array has been cleared to 0 before being used.
  265. */
  266. void clean_convert_img_array(CONVERT_IMG_ARRAY array,int16 count)
  267. {
  268.   int16 i;
  269.   if (!array)
  270.     return;
  271.   for (i=0;i<count;i++)
  272.     if (array[i])
  273.     free(array[i]);
  274.   free(array);
  275. }
  276.  
  277.  
  278.  
  279. int16 read_mem_stream(CONVERT_IMG_STREAM *p_stream,void *p_dest,uint16 p_bytecount)
  280. {
  281.   XP_ASSERT(p_stream);
  282.   if ((p_stream->m_streamsize==0) ||((p_stream->m_currentindex+(DWORD)p_bytecount)<p_stream->m_streamsize))
  283.   {
  284.     memcpy(p_dest,p_stream->m_mem+p_stream->m_currentindex,p_bytecount);
  285.     p_stream->m_currentindex+=p_bytecount;
  286.     return p_bytecount;
  287.   }
  288.   return 0;/*read past end of stream*/
  289. }
  290.  
  291. BYTE read_mem_stream_byte(CONVERT_IMG_STREAM *p_stream)
  292. {
  293.   XP_ASSERT(p_stream);
  294.   if ((p_stream->m_streamsize==0) ||((p_stream->m_currentindex+1)<p_stream->m_streamsize))
  295.   {
  296.     return p_stream->m_mem[p_stream->m_currentindex++];
  297.   }
  298.   XP_ASSERT(0);
  299.   return 0;/*read past end of stream*/
  300. }
  301.  
  302. int16 read_param(CONVERT_IMG_STREAM *p_input,void *p_dest,uint16 p_bytecount)
  303. {
  304.   XP_ASSERT(p_input);
  305.   if (CONVERT_MEMORY==p_input->m_type)
  306.     return read_mem_stream(p_input,p_dest,p_bytecount);
  307.   else if (CONVERT_FILE==p_input->m_type)
  308.     return ReadOK(p_input->m_file,p_dest,p_bytecount);
  309.   else
  310.   {
  311.     XP_ASSERT(0);
  312.     return -1;
  313.   }
  314. }
  315.  
  316. BYTE read_param_byte(CONVERT_IMG_STREAM *p_input)
  317. {
  318.   XP_ASSERT(p_input);
  319.   if (CONVERT_MEMORY==p_input->m_type)
  320.     return read_mem_stream_byte(p_input);
  321.   else if (CONVERT_FILE==p_input->m_type)
  322.     return (BYTE) getc(p_input->m_file); 
  323.   else
  324.   {
  325.     XP_ASSERT(0);
  326.     return 0;
  327.   }
  328. }
  329.  
  330.  
  331.