#line 1 "/h/et/m/h0/krause/PROGR/C/LibDev/Distribute/tifeps.ctr"
/* 
 * libbmeps - Bitmap to EPS conversion library
 * Copyright (C) 2000 - Dirk Krause
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 * In this package the copy of the GNU Library General Public License
 * is placed in file COPYING.
 */


#line 23 "/h/et/m/h0/krause/PROGR/C/LibDev/Distribute/tifeps.ctr"

#line 23 "/h/et/m/h0/krause/PROGR/C/LibDev/Distribute/tifeps.ctr"


#include <stdio.h>
#include <bmeps.h>
#include <bmepsco.h>

#if HAVE_TIFF_H
#include <tiff.h>
#include <tiffio.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#endif


#if HAVE_TIFF_H

static char def_name[] = { "unknown.tif" };

static int get_byte(uint32 ui, int what)
{
  int back = 0;
  switch(what) {
    case 3: {
      back = (ui & 255);
    } break;
    case 2: {
      back = ((ui >> 8) & 255);
    } break;
    case 1: {
      back = ((ui >> 16) & 255);
    } break;
    default: {
      back = ((ui >> 24) & 255);
    } break;
  }
  return back;
}

static int contains_trans(uint32 *raster, uint32 w, uint32 h)
{
  int back = 0;
  uint32 *ptr; uint32 x; uint32 y;
  
  ptr = raster; x = 0; y = 0;
  while((!back) && (y < h)) {
    x = 0;
    while((!back) && (x < w)) {
      if(get_byte(*ptr, 0) != 255) {
	back = 1;
      }
      ptr++; x++;
    }
    y++;
  } 
  return back;
}

static int contains_colors(uint32 *raster, uint32 w, uint32 h)
{
  int back = 0;
  uint32 x, y, *ptr;
  
  ptr = raster;
  y = 0;
  while((y < h) && (!back)) {
    x = 0;
    while((x < w) && (!back)) {
       if(get_byte(*ptr, 1) != get_byte(*ptr, 2)) {
	 back = 1;
       }
       if(get_byte(*ptr, 1) != get_byte(*ptr, 3)) {
	 back = 1;
       }
       ptr++;
       x++;
    }
    y++;
  } 
  return back;
}

static int mix_colors(int fg, int bg, int alpha, int tr)
{
  int back = 0;
  unsigned long f, b, a, bck;
  
  if(tr) { a = (255UL - alpha) ; }
  else   { a = alpha; }
  f = fg; b = bg;
  bck = ((a * f) + ((255UL - a) * b)) / 255UL;
  back = bck; 
  return back;
}

static int
bmeps_tiff_run(
  int cmd, FILE *out, FILE *in, char *name, 
  unsigned long *wptr, unsigned long *hptr
)
{
  int back = 0;
  int tmpok, not_finished;
  BmepsConfiguration oldcfg, newcfg;
  uint32 elem;
  int r, g, b, a, use_alpha, use_mix, use_trans, bgr, bgg, bgb, has_c, has_t;
  char buffer[4096], *tmp_filename;
  size_t sx;
  FILE *fp;
  TIFF *tif;
  uint32 w, h, x, y;
  size_t npixels;
  uint32 *raster, *rptr;
  
  bmeps_configure();
  bmeps_get_cfg(&oldcfg);
  bmeps_copy_cfg(&newcfg, &oldcfg);
  tmp_filename = bmeps_tmpname();
  tmpok = 0;
  if(tmp_filename) {
    fp = fopen(tmp_filename, "wb");
    if(fp) {
      tmpok = 1;
      while((sx = fread(buffer,1,sizeof(buffer),in)) > 0) {
	fwrite(buffer,1,sx,fp);
      }
      fclose(fp);
    }
    if(tmpok) {
      tif = TIFFOpen(tmp_filename, "r");
      if(tif) {
	TIFFGetField(tif,TIFFTAG_IMAGEWIDTH,&w);
	TIFFGetField(tif,TIFFTAG_IMAGELENGTH,&h);
	npixels = w * h;
	if(cmd) {
	  if(bmeps_get_draft()) {	/* draft only */
	    
	    bmeps_header(out, (name ? name : def_name), w, h);
	    bmeps_draft(out, w, h);
	    bmeps_footer(out);
	  } else {			/* real picture */
	    
	    raster = (uint32 *)_TIFFmalloc(npixels*(sizeof(uint32)));
	    if(raster) {
	      if(TIFFReadRGBAImage(tif,w,h,raster,0)) {
		
		use_alpha = bmeps_get_alpha();
		use_mix   = bmeps_get_mix();
		use_trans = bmeps_get_trans();
		bgr = bmeps_get_bg_red();
		bgg = bmeps_get_bg_green();
		bgb = bmeps_get_bg_blue();
	        /* image available */
		if(!(has_t = contains_trans(raster,w,h))) {
		  
		  use_alpha = 0;
		}
		if(newcfg.col) { 
		  has_c = 0;
		  if(has_t && ((bgr != bgg) || (bgr != bgb))) {
		    has_c = 1;
		  } else {
		    has_c = contains_colors(raster, w, h);
		  }
		  if(!has_c) { 
		    newcfg.col = 0;
		  }
		}
		bmeps_set_cfg(&newcfg);
		bmeps_header(out, (name ? name : def_name), w, h);
		if(use_alpha) {
		  bmeps_set_trans(1);
		}
		bmeps_begin_image(out, w, h);
		rptr = raster;
		not_finished = 1;
		y = h - 1;
		while(not_finished) {
		  for(x = 0; x < w; x++) {
		    rptr = &(raster[(y * w) + x]);
		    a = get_byte(*rptr, 0);
		    b = get_byte(*rptr, 1);
		    g = get_byte(*rptr, 2);
		    r = get_byte(*rptr, 3);
		    
		    if(use_alpha) {
		      if(use_mix) {
			r = mix_colors(r,bgr,a,use_trans);
			g = mix_colors(g,bgg,a,use_trans);
			b = mix_colors(b,bgb,a,use_trans);
		      }
		      bmeps_add_trans(255-a);
		    } 
		    bmeps_add_rgb(r,g,b);
		  }
		  if(y == 0) { not_finished = 0; }
		  y--;
		}
		bmeps_end_image(out);
		bmeps_footer(out);
		back = 1;
	      }
	      _TIFFfree(raster);
	    }
	  }
	} else {
	  if(wptr) { *wptr = w; }
	  if(hptr) { *hptr = h; }
	  if(wptr && hptr) {
	    back = 1;
	  }
	}
	TIFFClose(tif);
      }
#if HAVE_UNLINK
      
      unlink(tmp_filename);
#else
#if HAVE_REMOVE
      
      remove(tmp_filename);
#endif
#endif
    }
  }
  bmeps_set_cfg(&oldcfg);
  
  return back;
}
#endif

int bmeps_tiff(FILE *out, FILE *in, char *name)
{
  int back = 0;
#if HAVE_TIFF_H
  if(out && in) {
    back = bmeps_tiff_run(1,out,in,name,NULL,NULL);
  }
#endif
  return back;
}

int bmeps_tiff_wh(FILE *in, unsigned long *w, unsigned long *h)
{
  int back = 0;
#if HAVE_TIFF_H
  if(in && w && h) {
    back = bmeps_tiff_run(0,NULL,in,NULL,w,h);
  }
#endif
  return back;
}

int bmeps_tiff_bb(FILE *out, FILE *in, char *name)
{
  int back = 0;
#if HAVE_TIFF_H
  unsigned long w,h;
  if(out && in) {
    if(bmeps_tiff_wh(in,&w,&h)) {
      bmeps_bb(out,w,h); back = 1;
    }
  }
#endif
  return back;
}

#ifndef LINT
static char sccsId[] = 
{ "@(#)tifeps.ctr 1.13 08/17/01 (krause)\tTIFF to EPS conversion" };
#endif

