/* p_tiff.c
 * Copyright (C) 1997-98 Thomas Merz. All rights reserved.
 *
 * TIFF processing for PDFlib
 */

#include "p_intern.h"

#ifdef USE_TIFF

static void
pdf_data_source_TIFF_init(PDF *p, PDF_data_source *src)
{
  PDF_image	*image;

  image = (PDF_image *) src->private_data;
  image->cur_line = 0;

  src->buffer_length = image->components * image->width;
  src->buffer_start = 
  	PDF_malloc(src->buffer_length, "PDF_data_source_TIFF_init");
}

static bool
pdf_data_source_TIFF_fill(PDF *p, PDF_data_source *src)
{
  PDF_image	*image;
  int		col;
  byte		*dest;
  uint32	*s;

  image = (PDF_image *) src->private_data;

  if (image->cur_line++ == image->height)
    return false;

  src->next_byte = src->buffer_start;
  src->bytes_available = src->buffer_length;

  dest = src->buffer_start;
  s = image->raster + (image->height - 1 - image->cur_line) * image->width;
  
  switch (image->components) {
      case 1:
		  for (col = 0; col < image->width; col++, s++) {
			*dest++ = TIFFGetR(*s);
		  }
		  break;

      case 3:
		  for (col = 0; col < image->width; col++, s++) {
			*dest++ = TIFFGetR(*s);
			*dest++ = TIFFGetG(*s);
			*dest++ = TIFFGetB(*s);
		  }
		  break;

      default:
		pdf_error(p, PDF_FATAL, 
			"Unknown color space in TIFF image %s (%d components)", 
			image->filename, image->components);
  }

  return true;
}

static void
pdf_data_source_TIFF_terminate(PDF *p, PDF_data_source *src)
{
  PDF_image	*image;

  image = (PDF_image *) src->private_data;

  PDF_free((void *) src->buffer_start);
}

PDF_image *
PDF_open_TIFF(PDF *p, char *filename)
{
    PDF_image *image;
    int32 w, h;
    uint16 bpc;
    tsample_t components;
    size_t npixels;
    uint16	*rmap, *gmap, *bmap;

    image = (PDF_image *) PDF_malloc(sizeof(PDF_image), "PDF_open_TIFF");

    if (image == NULL)
	return NULL;

    image->tif = TIFFOpen(filename, "r");

    if (!image->tif) {
	PDF_free(image);
	return NULL;
    }

    TIFFGetField(image->tif, TIFFTAG_IMAGEWIDTH, &w);
    TIFFGetField(image->tif, TIFFTAG_IMAGELENGTH, &h);
    TIFFGetField(image->tif, TIFFTAG_BITSPERSAMPLE, &bpc);
    TIFFGetField(image->tif, TIFFTAG_SAMPLESPERPIXEL, &components);

    image->filename = filename;
    image->width		= w;
    image->height		= h;
    /* we use 8 bit to retrieve the image data in all cases */
    image->bpc			= 8;
    image->components	= components;
    image->compression	= none;
    image->closefunc	= PDF_close_TIFF;
    image->BitPixel		= 1 << image->bpc;
    image->indexed		= false;

    switch (image->components) {
	case 1:
		if (TIFFGetField(image->tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
			/* if it is a palette image we have to adapt these accordingly */
			image->colorspace	= DeviceRGB;
			image->components	= 3;
		} else
			/* plain old grayscale image */
			image->colorspace	= DeviceGray;
	    break;
	case 3:
	    image->colorspace	= DeviceRGB;
	    break;
	case 4:
	    image->colorspace	= DeviceCMYK;
	    break;
	default:
	    pdf_error(p, PDF_FATAL, 
		"Unknown color space in TIFF image %s (%d components)", 
		image->filename, image->components);
	    
    }

    image->src.init		= pdf_data_source_TIFF_init;
    image->src.fill		= pdf_data_source_TIFF_fill;
    image->src.terminate	= pdf_data_source_TIFF_terminate;
    image->src.private_data	= (void *) image;

    npixels = w * h;
    image->raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));

    if (image->raster == NULL ||
	!TIFFReadRGBAImage(image->tif, w, h, image->raster, 0)) {
	TIFFClose(image->tif);
	PDF_free(image);
	return NULL;
    }

    return image;
}

void
PDF_close_TIFF(PDF *p, PDF_image *image)
{
    _TIFFfree(image->raster);
    TIFFClose(image->tif);
    PDF_free(image);
}

#else	/* USE_TIFF */

/* Define dummies if we can't use TIFFlib */
PDF_image *
PDF_open_TIFF(PDF *p, char *filename)
{
    return false;
}

void
PDF_close_TIFF(PDF *p, PDF_image *image)
{
}

#endif	/* USE_TIFF */
