What Wolfgang changed was the tiff.m file in GNUstep gui. If you have
the old source code you could just replace that file and recompile
GNUstep gui. I attached that file to make this easier for you.

There is one thing we could do to verify that this is really the cause
of the problem. You could write out the generated tiff representation
into a file and check whether this looks correct when loaded into
another application. That way we would know whether it is the tiff
writing or the tiff reading that is wrong.

Fred

Am 03.03.2011 04:07, schrieb AN Indie:
> I guess , this is the bug fixed by Wolfgang Lux.
> 
>   Since I am using ubuntu, I need to wait for new deb package to
> release. All my packages are up to date. So please name the particular
> lib/package that which he fixed, so that  I can get  the source code,
> build it my self and verify.
> 
> My system configuration.
> 
> Ubuntu 10.04 LTS - the Lucid Lynx
> Pentium 4
> 
> #uname -a outputs:
> Linux localhost.localdomain 2.6.32-26-generic #48-Ubuntu SMP Wed Nov 24
> 09:00:03 UTC 2010 i686 GNU/Linux
> Packages:
> gnustep-base-runtime        1.19.3
> gnustep-back0.16-art        0.16.0-3
> libtiff4            3.9.2-2
> 
> I also attached screen shot of rendered image, which is same as that
> one  which I got from opengl.
> 
> Thank you.
> -AN Indie
> 
> 
> 
> On Mon, 28 Feb 2011 15:09:04 +0530, Fred Kiefer <[email protected]> wrote:
> 
>> Thank you very much for the example. As this reproduces the issue on
>> your machine without any GL code, I was off with my comments. Sorry for
>> that. Saturday I was ill, so I stopped coding for GNUstep but thought
>> that my code review skills would still work. I was wrong.
>>
>> Now, as for the test, it works perfectly on my machine. See attached
>> screen shot. This means we must have some differences between our
>> computers. Could you please provide some details of your setup?
>> Processor, Operation System and the used GNUstep backend (xlib, art or
>> cairo)? Perhaps also the version of your tiff library.
>>
>> There haven't been a lot of changes in the tiff handling of GNUstep gui.
>> Wolfgang Lux fixed a bug about two months ago, but this only affected
>> cases where the bits per sample != 8. This isn't the case here after the
>> conversion.
>>
>> Fred
>>
>>
>> Am 27.02.2011 17:28, schrieb AN Indie:
>>>  I accept their is mismatch between parameter/arguments. But this code
>>> just works!
>>> [
>>>  But good news is, I was able to reproduce the bug in package
>>> gnustep-examples-1.2.0
>>>
>>> I modified NSImage test case a little and  reproduced this bug!!
>>>
>>>
>>> I changed
>>>
>>>
>>> image = [[NSImage alloc] initWithContentsOfFile: file ];
>>> [mview setImage: image];
>>>
>>> with
>>>
>>>
>>> image = [[NSImage alloc] initWithContentsOfFile: file ];
>>> NSImage  * aximage =  [[NSImage alloc] initWithData:[image
>>> TIFFRepresentationUsingCompression:NSTIFFCompressionNone factor:0]];
>>> [mview setImage: aximage];
>>>
>>> An now  the gray scale image is not renders properly.
>>>
>>>
>>> I attached test case along with this mail. Please confirm with latest
>>> GNUstep as I am using the older version.
>>>
>>> -Thanks
>>> AN Indie

/* 
   tiff.m

   Functions for dealing with tiff images.

   Copyright (C) 1996,1999-2010 Free Software Foundation, Inc.
   
   Author:  Adam Fedor <[email protected]>
   Date: Feb 1996

   Support for writing tiffs: Richard Frith-Macdonald

   This file is part of the GNUstep GUI Library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; see the file COPYING.LIB.
   If not, see <http://www.gnu.org/licenses/> or write to the 
   Free Software Foundation, 51 Franklin Street, Fifth Floor, 
   Boston, MA 02110-1301, USA.
*/ 

/* Code in NSTiffRead, NSTiffGetInfo, and NSTiffGetColormap 
   is derived from tif_getimage, by Sam Leffler. See the copyright below.
*/

/*
 * Copyright (c) 1991, 1992, 1993, 1994 Sam Leffler
 * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and 
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Sam Leffler and Silicon Graphics.
 * 
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 * 
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 * OF THIS SOFTWARE.
 */

#include "config.h"
#include "nsimage-tiff.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSString.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSEnumerator.h>
#include "GSGuiPrivate.h"

#include <math.h>
#include <stdlib.h>
#include <string.h>
#ifndef __WIN32__
#include <unistd.h>		/* for L_SET, etc definitions */
#endif /* !__WIN32__ */

typedef struct {
  char* data;
  long  size;
  long  position;
  char  mode;
  char **outdata;
  long *outposition;
} chandle_t;

static int tiff_error_handler_set = 0;

static void
NSTiffError(const char *func, const char *msg, va_list ap)
{
  NSString *format;

  format = [NSString stringWithFormat: @"Tiff Error (%s) %s", func, msg];
  NSLogv (format, ap);
}

static void 
NSTiffWarning(const char *func, const char *msg, va_list ap)
{
  NSString *format;

  format = [NSString stringWithFormat: @"Tiff Warning (%s) %s", func, msg];
  format = [NSString stringWithFormat: format  arguments: ap];
  NSDebugLLog (@"NSTiff", @"%@", format);
}

/* Client functions that provide reading/writing of data for libtiff */
static tsize_t
TiffHandleRead(thandle_t handle, tdata_t buf, tsize_t count)
{
  chandle_t* chand = (chandle_t *)handle;
  if (chand->position >= chand->size)
    return 0;
  if (chand->position + count > chand->size)
    count = chand->size - chand->position;
  memcpy(buf, chand->data + chand->position, count);
  return count;
}

static tsize_t
TiffHandleWrite(thandle_t handle, tdata_t buf, tsize_t count)
{
  chandle_t* chand = (chandle_t *)handle;
  if (chand->mode == 'r')
    return 0;
  if (chand->position + count > chand->size)
    {
      chand->size = chand->position + count + 1;
      chand->data = objc_realloc(chand->data, chand->size);
      *(chand->outdata) = chand->data;
      if (chand->data == NULL)
	return 0;
    }
  memcpy(chand->data + chand->position, buf, count);
  chand->position += count;
  if (chand->position > *(chand->outposition))
    *(chand->outposition) = chand->position;
  
  return count;
}

static toff_t
TiffHandleSeek(thandle_t handle, toff_t offset, int mode)
{
  chandle_t* chand = (chandle_t *)handle;
  switch(mode) 
    {
    case SEEK_SET: chand->position = offset; break;
    case SEEK_CUR: chand->position += offset; break;
    case SEEK_END: 
      if (offset > 0 && chand->mode == 'r')
        return 0;
      chand->position += offset; break;
      break;
    }
  return chand->position;
}

static int
TiffHandleClose(thandle_t handle)
{
  chandle_t* chand = (chandle_t *)handle;

  /* Presumably, we don't need the handle anymore */
  free(chand);
  return 0;
}

static toff_t
TiffHandleSize(thandle_t handle)
{
  chandle_t* chand = (chandle_t *)handle;
  return chand->size;
}

static int
TiffHandleMap(thandle_t handle, tdata_t* data, toff_t* size)
{
  chandle_t* chand = (chandle_t *)handle;
  
  *data = chand->data;
  *size = chand->size;
    
  return 1;
}

static void
TiffHandleUnmap(thandle_t handle, tdata_t data, toff_t size)
{
  /* Nothing to unmap. */
}

/* Open a tiff from a stream. Returns NULL if can't read tiff information.  */
TIFF* 
NSTiffOpenDataRead(const char* data, long size)
{
  chandle_t* handle;

  if (tiff_error_handler_set == 0)
    {
      tiff_error_handler_set = 1;
      TIFFSetErrorHandler(NSTiffError);
      TIFFSetWarningHandler(NSTiffWarning);
    }

  handle = malloc(sizeof(chandle_t));
  handle->data = (char*)data;
  handle->outdata = 0;
  handle->position = 0;
  handle->outposition = 0;
  handle->size = size;
  handle->mode = 'r';
  return TIFFClientOpen("GSTiffReadData", "r",
			(thandle_t)handle,
			TiffHandleRead, TiffHandleWrite,
			TiffHandleSeek, TiffHandleClose,
			TiffHandleSize,
			TiffHandleMap, TiffHandleUnmap);
}

TIFF* 
NSTiffOpenDataWrite(char **data, long *size)
{
  chandle_t* handle;
  handle = malloc(sizeof(chandle_t));
  handle->data = *data;
  handle->outdata = data;
  handle->position = 0;
  handle->outposition = size;
  handle->size = *size;
  handle->mode = 'w';
  return TIFFClientOpen("GSTiffWriteData", "w",
			(thandle_t)handle,
			TiffHandleRead, TiffHandleWrite,
			TiffHandleSeek, TiffHandleClose,
			TiffHandleSize,
			TiffHandleMap, TiffHandleUnmap);
}

int  
NSTiffClose(TIFF* image)
{
  TIFFClose(image);
  return 0;
}

int   
NSTiffGetImageCount(TIFF* image)
{
  int dircount = 1;

  if (image == NULL)
    return 0;

  while (TIFFReadDirectory(image))
    {
      dircount++;
    } 
  return dircount;
}

/* Read some information about the image. Note that currently we don't
   determine numImages. */
NSTiffInfo *      
NSTiffGetInfo(int imageNumber, TIFF* image)
{
  NSTiffInfo* info;
  uint16 *sample_info = NULL;

  if (image == NULL)
    return NULL;

  info = malloc(sizeof(NSTiffInfo));
  memset(info, 0, sizeof(NSTiffInfo));
  if (imageNumber >= 0)
    {
      if (TIFFSetDirectory(image, imageNumber) == 0)
	return NULL;
      info->imageNumber = imageNumber;
    }
  
  TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &info->width);
  TIFFGetField(image, TIFFTAG_IMAGELENGTH, &info->height);
  TIFFGetField(image, TIFFTAG_COMPRESSION, &info->compression);
  if (info->compression == COMPRESSION_JPEG)
    TIFFGetField(image, TIFFTAG_JPEGQUALITY, &info->quality);
  TIFFGetField(image, TIFFTAG_SUBFILETYPE, &info->subfileType);
  TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &info->extraSamples, &sample_info);
  info->extraSamples = (info->extraSamples == 1 
			&& ((sample_info[0] == EXTRASAMPLE_ASSOCALPHA) 
			    || (sample_info[0] == EXTRASAMPLE_UNASSALPHA)));
  info->assocAlpha = (info->extraSamples == 1 
		      && sample_info[0] == EXTRASAMPLE_ASSOCALPHA);

  /* If the following tags aren't present then use the TIFF defaults. */
  TIFFGetFieldDefaulted(image, TIFFTAG_BITSPERSAMPLE, &info->bitsPerSample);
  TIFFGetFieldDefaulted(image, TIFFTAG_SAMPLESPERPIXEL, 
			&info->samplesPerPixel);
  TIFFGetFieldDefaulted(image, TIFFTAG_PLANARCONFIG, 
			&info->planarConfig);

  /* If TIFFTAG_PHOTOMETRIC is not present then assign a reasonable default.
     The TIFF 5.0 specification doesn't give a default. */
  if (!TIFFGetField(image, TIFFTAG_PHOTOMETRIC, &info->photoInterp)) 
    {
      switch (info->samplesPerPixel) 
	{
	case 1:
	  info->photoInterp = PHOTOMETRIC_MINISBLACK;
	  break;
	case 3: case 4:
	  info->photoInterp = PHOTOMETRIC_RGB;
	  break;
	default:
	  TIFFError(TIFFFileName(image),
		    "Missing needed \"PhotometricInterpretation\" tag");
	  return NULL;
	}
      TIFFError(TIFFFileName(image),
		"No \"PhotometricInterpretation\" tag, assuming %s\n",
		info->photoInterp == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
    }

  return info;
}

#define READ_SCANLINE(sample)				\
  if (TIFFReadScanline(image, buf, row, sample) != 1)	\
    {							\
      error = 1;					\
      break;						\
    }

/* Read an image into a data array.  The data array is assumed to have been
   already allocated to the correct size.

   Note that palette images are implicitly coverted to 24-bit contig
   direct color images. Thus the data array should be large 
   enough to hold this information. */
int
NSTiffRead(TIFF *image, NSTiffInfo *info, unsigned char *data)
{
  int     i;
  unsigned int row, col;
  int	  error = 0;
  uint8* outP;
  uint8* buf;
  uint8* raster;
  NSTiffColormap* map;
  int scan_line_size;

  if (data == NULL)
    return -1;
	
  map = NULL;
  if (info->photoInterp == PHOTOMETRIC_PALETTE) 
    {
      map = NSTiffGetColormap(image);
      if (!map)
	return -1;
    }

  scan_line_size = TIFFScanlineSize(image);
  buf = _TIFFmalloc(scan_line_size);
  
  raster = (uint8 *)data;
  outP = raster;
  switch (info->photoInterp) 
    {
    case PHOTOMETRIC_MINISBLACK:
    case PHOTOMETRIC_MINISWHITE:
      if (info->planarConfig == PLANARCONFIG_CONTIG) 
	{
	  for (row = 0; row < info->height; ++row) 
	    {
	      READ_SCANLINE(0);
	      memcpy(outP, buf, scan_line_size);
	      outP += scan_line_size;
	    }
	} 
      else 
	{
	  for (i = 0; i < info->samplesPerPixel; i++)
	    for (row = 0; row < info->height; ++row) 
	      {
		READ_SCANLINE(i);
		memcpy(outP, buf, scan_line_size);
		outP += scan_line_size;
	      }
	}
      break;
    case PHOTOMETRIC_PALETTE:
      {
	for (row = 0; row < info->height; ++row) 
	  {
	    uint8 *inP;
	    READ_SCANLINE(0);
	    inP = buf;
	    for (col = 0; col < info->width; col++) 
	      {
		*outP++ = map->red[*inP] / 256;
		*outP++ = map->green[*inP] / 256;
		*outP++ = map->blue[*inP] / 256;
		inP++;
	      }
	  }
	free(map);
      }
      break;
    case PHOTOMETRIC_RGB:
      if (info->planarConfig == PLANARCONFIG_CONTIG) 
	{
	  for (row = 0; row < info->height; ++row) 
	    {
	      READ_SCANLINE(0);
	      memcpy(outP, buf, scan_line_size);
	      outP += scan_line_size;
	    }
	} 
      else 
	{
	  for (i = 0; i < info->samplesPerPixel; i++)
	    for (row = 0; row < info->height; ++row) 
	      {
		READ_SCANLINE(i);
		memcpy(outP, buf, scan_line_size);
		outP += scan_line_size;
	      }
	}
      break;
    default:
      NSLog(@"Tiff: reading photometric %d not supported", info->photoInterp);
      error = 1;
      break;
    }
    
  _TIFFfree(buf);
  return error;
}

#define WRITE_SCANLINE(sample) \
	if (TIFFWriteScanline(image, buf, row, sample) != 1) { \
	    error = 1; \
	    break; \
	}

int  
NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
{
  tdata_t	buf = (tdata_t)data;
  uint16        sample_info[2];
  int		i;
  unsigned int 	row;
  int           error = 0;
  int           scan_line_size;

  TIFFSetField(image, TIFFTAG_IMAGEWIDTH, info->width);
  TIFFSetField(image, TIFFTAG_IMAGELENGTH, info->height);
  TIFFSetField(image, TIFFTAG_COMPRESSION, info->compression);
  if (info->compression == COMPRESSION_JPEG)
    TIFFSetField(image, TIFFTAG_JPEGQUALITY, info->quality);
  TIFFSetField(image, TIFFTAG_SUBFILETYPE, info->subfileType);
  TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, info->bitsPerSample);
  TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, info->samplesPerPixel);
  TIFFSetField(image, TIFFTAG_PLANARCONFIG, info->planarConfig);
  TIFFSetField(image, TIFFTAG_PHOTOMETRIC, info->photoInterp);

  if (info->assocAlpha)
    sample_info[0] = EXTRASAMPLE_ASSOCALPHA;
  else
    sample_info[0] = EXTRASAMPLE_UNASSALPHA;
  TIFFSetField(image, TIFFTAG_EXTRASAMPLES, info->extraSamples, sample_info);
  scan_line_size = TIFFScanlineSize(image);

  switch (info->photoInterp) 
    {
      case PHOTOMETRIC_MINISBLACK:
      case PHOTOMETRIC_MINISWHITE:
	if (info->planarConfig == PLANARCONFIG_CONTIG) 
	  {
	    for (row = 0; row < info->height; ++row) 
	      {
		WRITE_SCANLINE(0)
		buf += scan_line_size;
	      }
	  } 
	else 
	  {
	    for (i = 0; i < info->samplesPerPixel; i++)
	      {
		for (row = 0; row < info->height; ++row) 
		  {
		    WRITE_SCANLINE(i)
		    buf += scan_line_size;
		  }
	      }
	  }
	break;

      case PHOTOMETRIC_RGB:
	if (info->planarConfig == PLANARCONFIG_CONTIG) 
	  {
	    for (row = 0; row < info->height; ++row) 
	      {
		WRITE_SCANLINE(0)
		buf += scan_line_size;
	      }
	  } 
	else 
	  {
	    for (i = 0; i < info->samplesPerPixel; i++)
	      {
		for (row = 0; row < info->height; ++row) 
		  {
		    WRITE_SCANLINE(i)
		    buf += scan_line_size;
		  }
	      }
	  }
	break;

      default:
	NSLog(@"Tiff: photometric %d for image %s not supported", 
	      info->photoInterp, TIFFFileName(image));
	return -1;
	break;
    }
    
  return error;
}

/*------------------------------------------------------------------------*/

/* Many programs get TIFF colormaps wrong.  They use 8-bit colormaps
   instead of 16-bit colormaps.  This function is a heuristic to
   detect and correct this. */
static int
CheckAndCorrectColormap(NSTiffColormap* map)
{
  register unsigned int i;

  for (i = 0; i < map->size; i++)
    if ((map->red[i] > 255)||(map->green[i] > 255)||(map->blue[i] > 255))
      return 16;

#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
  for (i = 0; i < map->size; i++) 
    {
      map->red[i] = CVT(map->red[i]);
      map->green[i] = CVT(map->green[i]);
      map->blue[i] = CVT(map->blue[i]);
    }
  return 8;
}

/* Gets the colormap for the image if there is one. Returns a
   NSTiffColormap if one was found.
*/
NSTiffColormap *
NSTiffGetColormap(TIFF* image)
{
  NSTiffInfo* info;
  NSTiffColormap* map;

  /* Re-read the tiff information. We pass -1 as the image number which
     means just read the current image. */
  info = NSTiffGetInfo(-1, image);
  if (info->photoInterp != PHOTOMETRIC_PALETTE)
    return NULL;

  map = malloc(sizeof(NSTiffColormap));
  map->size = 1 << info->bitsPerSample;

  if (!TIFFGetField(image, TIFFTAG_COLORMAP,
		    &map->red, &map->green, &map->blue)) 
    {
      TIFFError(TIFFFileName(image), "Missing required \"Colormap\" tag");
      free(map);
      return NULL;
    }
  if (CheckAndCorrectColormap(map) == 8)
    TIFFWarning(TIFFFileName(image), "Assuming 8-bit colormap");

  free(info);
  return map;
}

int NSTiffIsCodecConfigured(unsigned int codec)
{
#if (TIFFLIB_VERSION >= 20041016)
  // starting with version 3.7.0 we can ask libtiff what it is configured to do
  return TIFFIsCODECConfigured(codec);
#else
  // we check the tiffconf.h
#include <tiffconf.h>
#ifndef CCITT_SUPPORT
#  define CCITT_SUPPORT 0
#else
#  define CCITT_SUPPORT 1
#endif
#ifndef PACKBITS_SUPPORT
#  define PACKBITS_SUPPORT 0
#else
#  define PACKBITS_SUPPORT 1
#endif
#ifndef OJPEG_SUPPORT
#  define OJPEG_SUPPORT 0
#else
#  define OJPEG_SUPPORT 1
#endif
#ifndef LZW_SUPPORT
#  define LZW_SUPPORT 0
#else
#  define LZW_SUPPORT 1
#endif
#ifndef NEXT_SUPPORT
#  define NEXT_SUPPORT 0
#else
#  define NEXT_SUPPORT 1
#endif
#ifndef JPEG_SUPPORT
#  define JPEG_SUPPORT 0
#else
#  define JPEG_SUPPORT 1
#endif
/* If this fails, your libtiff is obsolete! Come to think of it
 * if you even are compiling this part your libtiff is obsolete. */
  switch (codec)
  {
    case COMPRESSION_NONE: return 1;
    case COMPRESSION_CCITTFAX3: return CCITT_SUPPORT;
    case COMPRESSION_CCITTFAX4: return CCITT_SUPPORT;
    case COMPRESSION_JPEG: return JPEG_SUPPORT;
    case COMPRESSION_PACKBITS: return PACKBITS_SUPPORT;
    case COMPRESSION_OJPEG: return OJPEG_SUPPORT;
    case COMPRESSION_LZW: return LZW_SUPPORT;
    case COMPRESSION_NEXT: return NEXT_SUPPORT;
    default:
      return 0;
  }
#endif
}


_______________________________________________
Discuss-gnustep mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/discuss-gnustep

Reply via email to