1996-10-18 17:14:13 +00:00
|
|
|
/*
|
|
|
|
tiff.m
|
|
|
|
|
|
|
|
Functions for dealing with tiff images.
|
|
|
|
|
2017-04-24 10:42:32 +00:00
|
|
|
Copyright (C) 1996,1999-2010, 2017 Free Software Foundation, Inc.
|
1996-08-22 18:51:08 +00:00
|
|
|
|
1996-10-18 17:14:13 +00:00
|
|
|
Author: Adam Fedor <fedor@colorado.edu>
|
1996-08-22 18:51:08 +00:00
|
|
|
Date: Feb 1996
|
1999-12-28 16:02:01 +00:00
|
|
|
|
|
|
|
Support for writing tiffs: Richard Frith-Macdonald
|
|
|
|
|
1996-10-18 17:14:13 +00:00
|
|
|
This file is part of the GNUstep GUI Library.
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
2007-10-29 21:16:17 +00:00
|
|
|
modify it under the terms of the GNU Lesser General Public
|
1996-08-22 18:51:08 +00:00
|
|
|
License as published by the Free Software Foundation; either
|
2008-06-10 04:01:49 +00:00
|
|
|
version 2 of the License, or (at your option) any later version.
|
2007-10-29 21:16:17 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2007-10-29 21:16:17 +00:00
|
|
|
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
|
1996-10-18 17:14:13 +00:00
|
|
|
License along with this library; see the file COPYING.LIB.
|
2007-10-29 21:16:17 +00:00
|
|
|
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.
|
|
|
|
*/
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
|
|
|
|
2003-07-31 23:52:10 +00:00
|
|
|
#include "config.h"
|
|
|
|
#include "nsimage-tiff.h"
|
2011-03-04 11:33:22 +00:00
|
|
|
#import <Foundation/NSArray.h>
|
|
|
|
#import <Foundation/NSDebug.h>
|
|
|
|
#import <Foundation/NSString.h>
|
|
|
|
#import <Foundation/NSDictionary.h>
|
|
|
|
#import <Foundation/NSEnumerator.h>
|
|
|
|
#import "GSGuiPrivate.h"
|
1997-02-18 00:29:25 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
#include <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
1996-10-07 20:29:00 +00:00
|
|
|
#ifndef __WIN32__
|
1996-08-22 18:51:08 +00:00
|
|
|
#include <unistd.h> /* for L_SET, etc definitions */
|
1996-10-07 20:29:00 +00:00
|
|
|
#endif /* !__WIN32__ */
|
1996-08-22 18:51:08 +00:00
|
|
|
|
2015-01-23 13:29:38 +00:00
|
|
|
#if !defined(TIFF_VERSION_CLASSIC)
|
2015-01-11 21:51:20 +00:00
|
|
|
// This only got added in version 4 of libtiff, but TIFFLIB_VERSION is unusable to differentiate here
|
|
|
|
typedef tsize_t tmsize_t;
|
|
|
|
#endif
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
typedef struct {
|
|
|
|
char* data;
|
|
|
|
long size;
|
|
|
|
long position;
|
2007-11-11 18:10:42 +00:00
|
|
|
char mode;
|
1999-12-28 16:02:01 +00:00
|
|
|
char **outdata;
|
|
|
|
long *outposition;
|
1996-08-22 18:51:08 +00:00
|
|
|
} chandle_t;
|
|
|
|
|
2000-04-13 19:23:16 +00:00
|
|
|
static int tiff_error_handler_set = 0;
|
|
|
|
|
|
|
|
static void
|
2001-03-06 03:29:55 +00:00
|
|
|
NSTiffError(const char *func, const char *msg, va_list ap)
|
2000-04-13 19:23:16 +00:00
|
|
|
{
|
|
|
|
NSString *format;
|
|
|
|
|
|
|
|
format = [NSString stringWithFormat: @"Tiff Error (%s) %s", func, msg];
|
|
|
|
NSLogv (format, ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-06 03:29:55 +00:00
|
|
|
NSTiffWarning(const char *func, const char *msg, va_list ap)
|
2000-04-13 19:23:16 +00:00
|
|
|
{
|
|
|
|
NSString *format;
|
|
|
|
|
|
|
|
format = [NSString stringWithFormat: @"Tiff Warning (%s) %s", func, msg];
|
2004-09-18 13:16:55 +00:00
|
|
|
format = [NSString stringWithFormat: format arguments: ap];
|
|
|
|
NSDebugLLog (@"NSTiff", @"%@", format);
|
2000-04-13 19:23:16 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* Client functions that provide reading/writing of data for libtiff */
|
2015-01-23 13:29:38 +00:00
|
|
|
static tmsize_t
|
|
|
|
TiffHandleRead(thandle_t handle, void* buf, tmsize_t count)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-01-23 13:29:38 +00:00
|
|
|
static tmsize_t
|
|
|
|
TiffHandleWrite(thandle_t handle, void* buf, tmsize_t count)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
chandle_t* chand = (chandle_t *)handle;
|
2007-11-11 18:10:42 +00:00
|
|
|
if (chand->mode == 'r')
|
1996-08-22 18:51:08 +00:00
|
|
|
return 0;
|
|
|
|
if (chand->position + count > chand->size)
|
|
|
|
{
|
|
|
|
chand->size = chand->position + count + 1;
|
2011-04-08 23:21:55 +00:00
|
|
|
chand->data = realloc(chand->data, chand->size);
|
1999-12-28 16:02:01 +00:00
|
|
|
*(chand->outdata) = chand->data;
|
1996-08-22 18:51:08 +00:00
|
|
|
if (chand->data == NULL)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
memcpy(chand->data + chand->position, buf, count);
|
1999-12-28 16:02:01 +00:00
|
|
|
chand->position += count;
|
|
|
|
if (chand->position > *(chand->outposition))
|
|
|
|
*(chand->outposition) = chand->position;
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
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:
|
2015-10-10 19:18:33 +00:00
|
|
|
// FIXME: Not sure whether this check is correct
|
2007-11-11 18:10:42 +00:00
|
|
|
if (offset > 0 && chand->mode == 'r')
|
|
|
|
return 0;
|
2015-10-10 19:18:33 +00:00
|
|
|
chand->position = chand->size - ((chand->size > 0) ? 1 : 0) + offset;
|
1996-08-22 18:51:08 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return chand->position;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
TiffHandleClose(thandle_t handle)
|
|
|
|
{
|
|
|
|
chandle_t* chand = (chandle_t *)handle;
|
|
|
|
|
|
|
|
/* Presumably, we don't need the handle anymore */
|
2011-02-28 15:43:25 +00:00
|
|
|
free(chand);
|
1996-08-22 18:51:08 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static toff_t
|
|
|
|
TiffHandleSize(thandle_t handle)
|
|
|
|
{
|
|
|
|
chandle_t* chand = (chandle_t *)handle;
|
|
|
|
return chand->size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-01-23 13:29:38 +00:00
|
|
|
TiffHandleMap(thandle_t handle, void** data, toff_t* size)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
chandle_t* chand = (chandle_t *)handle;
|
|
|
|
|
|
|
|
*data = chand->data;
|
|
|
|
*size = chand->size;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2015-01-23 13:29:38 +00:00
|
|
|
TiffHandleUnmap(thandle_t handle, void* data, toff_t size)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
/* Nothing to unmap. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Open a tiff from a stream. Returns NULL if can't read tiff information. */
|
|
|
|
TIFF*
|
1999-12-28 16:02:01 +00:00
|
|
|
NSTiffOpenDataRead(const char* data, long size)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
chandle_t* handle;
|
2000-04-13 19:23:16 +00:00
|
|
|
|
|
|
|
if (tiff_error_handler_set == 0)
|
|
|
|
{
|
|
|
|
tiff_error_handler_set = 1;
|
|
|
|
TIFFSetErrorHandler(NSTiffError);
|
|
|
|
TIFFSetWarningHandler(NSTiffWarning);
|
|
|
|
}
|
|
|
|
|
2011-02-28 15:43:25 +00:00
|
|
|
handle = malloc(sizeof(chandle_t));
|
1999-12-28 16:02:01 +00:00
|
|
|
handle->data = (char*)data;
|
|
|
|
handle->outdata = 0;
|
1996-08-22 18:51:08 +00:00
|
|
|
handle->position = 0;
|
1999-12-28 16:02:01 +00:00
|
|
|
handle->outposition = 0;
|
1996-08-22 18:51:08 +00:00
|
|
|
handle->size = size;
|
2007-11-11 18:10:42 +00:00
|
|
|
handle->mode = 'r';
|
2001-09-01 04:20:55 +00:00
|
|
|
return TIFFClientOpen("GSTiffReadData", "r",
|
1999-12-28 16:02:01 +00:00
|
|
|
(thandle_t)handle,
|
|
|
|
TiffHandleRead, TiffHandleWrite,
|
|
|
|
TiffHandleSeek, TiffHandleClose,
|
|
|
|
TiffHandleSize,
|
|
|
|
TiffHandleMap, TiffHandleUnmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
TIFF*
|
|
|
|
NSTiffOpenDataWrite(char **data, long *size)
|
|
|
|
{
|
|
|
|
chandle_t* handle;
|
2011-02-28 15:43:25 +00:00
|
|
|
handle = malloc(sizeof(chandle_t));
|
1999-12-28 16:02:01 +00:00
|
|
|
handle->data = *data;
|
|
|
|
handle->outdata = data;
|
|
|
|
handle->position = 0;
|
|
|
|
handle->outposition = size;
|
|
|
|
handle->size = *size;
|
2007-11-11 18:10:42 +00:00
|
|
|
handle->mode = 'w';
|
2001-09-01 04:20:55 +00:00
|
|
|
return TIFFClientOpen("GSTiffWriteData", "w",
|
1996-08-22 18:51:08 +00:00
|
|
|
(thandle_t)handle,
|
|
|
|
TiffHandleRead, TiffHandleWrite,
|
|
|
|
TiffHandleSeek, TiffHandleClose,
|
|
|
|
TiffHandleSize,
|
|
|
|
TiffHandleMap, TiffHandleUnmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
NSTiffClose(TIFF* image)
|
|
|
|
{
|
|
|
|
TIFFClose(image);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-04-13 19:23:16 +00:00
|
|
|
int
|
|
|
|
NSTiffGetImageCount(TIFF* image)
|
|
|
|
{
|
|
|
|
int dircount = 1;
|
|
|
|
|
|
|
|
if (image == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
while (TIFFReadDirectory(image))
|
|
|
|
{
|
|
|
|
dircount++;
|
|
|
|
}
|
2015-10-10 19:18:33 +00:00
|
|
|
TIFFSetDirectory(image, 0);
|
2000-04-13 19:23:16 +00:00
|
|
|
return dircount;
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* Read some information about the image. Note that currently we don't
|
|
|
|
determine numImages. */
|
|
|
|
NSTiffInfo *
|
|
|
|
NSTiffGetInfo(int imageNumber, TIFF* image)
|
|
|
|
{
|
|
|
|
NSTiffInfo* info;
|
2021-11-08 21:46:25 +00:00
|
|
|
uint16_t *sample_info = NULL;
|
1996-08-22 18:51:08 +00:00
|
|
|
|
2000-04-13 19:23:16 +00:00
|
|
|
if (image == NULL)
|
|
|
|
return NULL;
|
1996-08-22 18:51:08 +00:00
|
|
|
|
2011-02-28 15:43:25 +00:00
|
|
|
info = malloc(sizeof(NSTiffInfo));
|
1996-08-22 18:51:08 +00:00
|
|
|
memset(info, 0, sizeof(NSTiffInfo));
|
|
|
|
if (imageNumber >= 0)
|
2000-04-13 19:23:16 +00:00
|
|
|
{
|
2003-09-08 02:07:53 +00:00
|
|
|
if (TIFFSetDirectory(image, imageNumber) == 0)
|
|
|
|
return NULL;
|
2000-04-13 19:23:16 +00:00
|
|
|
info->imageNumber = imageNumber;
|
|
|
|
}
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &info->width);
|
|
|
|
TIFFGetField(image, TIFFTAG_IMAGELENGTH, &info->height);
|
|
|
|
TIFFGetField(image, TIFFTAG_COMPRESSION, &info->compression);
|
2001-09-01 04:20:55 +00:00
|
|
|
if (info->compression == COMPRESSION_JPEG)
|
|
|
|
TIFFGetField(image, TIFFTAG_JPEGQUALITY, &info->quality);
|
1996-08-22 18:51:08 +00:00
|
|
|
TIFFGetField(image, TIFFTAG_SUBFILETYPE, &info->subfileType);
|
2000-04-16 16:27:47 +00:00
|
|
|
TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &info->extraSamples, &sample_info);
|
2000-04-18 16:58:14 +00:00
|
|
|
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);
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
/* 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");
|
2003-09-08 02:07:53 +00:00
|
|
|
return NULL;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
TIFFError(TIFFFileName(image),
|
|
|
|
"No \"PhotometricInterpretation\" tag, assuming %s\n",
|
|
|
|
info->photoInterp == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
|
|
|
|
}
|
|
|
|
|
2011-04-21 22:19:06 +00:00
|
|
|
{
|
2021-11-08 21:46:25 +00:00
|
|
|
uint16_t resolution_unit;
|
2011-04-21 22:19:06 +00:00
|
|
|
float xres, yres;
|
|
|
|
if (TIFFGetField(image, TIFFTAG_XRESOLUTION, &xres)
|
|
|
|
&& TIFFGetField(image, TIFFTAG_YRESOLUTION, &yres))
|
|
|
|
{
|
|
|
|
TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &resolution_unit);
|
|
|
|
if (resolution_unit == 2) // Inch
|
|
|
|
{
|
|
|
|
info->xdpi = xres;
|
|
|
|
info->ydpi = yres;
|
|
|
|
}
|
|
|
|
else if (resolution_unit == 3) // Centimeter
|
|
|
|
{
|
|
|
|
info->xdpi = xres * 2.54;
|
|
|
|
info->ydpi = yres * 2.54;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
2000-04-13 19:23:16 +00:00
|
|
|
#define READ_SCANLINE(sample) \
|
|
|
|
if (TIFFReadScanline(image, buf, row, sample) != 1) \
|
|
|
|
{ \
|
|
|
|
error = 1; \
|
|
|
|
break; \
|
|
|
|
}
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
/* 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
|
2005-01-21 21:43 Alexander Malmberg <alexander@malmberg.org>
Various whitespace cleanups, comment type fixes, and changes
to avoid warnings from recent versions of gcc.
* Headers/Additions/GNUstepGUI/GSToolbar.h (-_toolbars): Declare.
* Source/NSWindow+Toolbar.m: Remove conflicting declaration of
[NSToolbar -_toolbars].
* Headers/Additions/GNUstepGUI/GSServicesManager.h,
Source/GSServicesMananger.m (-item2title:, -validateMenuItem:):
Adjust argument types.
* Headers/AppKit/NSMenu.h (-validateMenuItem:): Adjust argument
type.
* Source/NSTextView.m (-sizeToFit): Don't use size uninitialized
if neither resizable flags is set.
(-insertText:): Adjust argument type.
* Headers/AppKit/NSResponder.h, Source/NSResponder.m (-insertText:):
Adjust argument type. Document.
* Headers/AppKit/NSView.h: Change type of ivar _window to NSWindow *.
* Source/GSTitleView.m (-mouseDown:): Always initialize
startWindowOrigin.
* Source/NSApplication.m (-setApplicationIconImage:): Add casts
to avoid warnings.
* Source/NSCell.m (-cellSize): Add default: case.
* Source/NSPasteboard.m
([GSFiltered -pasteboard:provideDataForType:]): Detect and warn if we
can't find a filter that will get us the desired type.
* Source/NSProgressIndicator.m: Comment out unused variable 'images'.
* Source/NSBezierPath.m: Declare GSBezierPath fully before using it.
(-bezierPathByFlatteningPath, -bezierPathByReversingPath): Make sure
variables are always initialized.
* Source/NSMenuView.m,
* Source/NSPrintOperation.m,
* Source/NSSplitView.m,
* Source/NSTableHeaderView.m: Make sure variables are always
initialized.
* Source/NSBox.m,
* Source/NSImageview.m,
* Source/NSText.m,
* Source/NSTextStorage.m: Add missing includes.
* Source/GSKeyBindingTable.m,
* Source/GSLayoutManager.m,
* Source/NSBitmapImageRep+PNM.m,
* Source/NSBundleAdditions.m,
* Source/NSLayoutManager.m,
* Source/nsimage-tiff.h,
* Source/tiff.m,
* Headers/Additions/GNUstepGUI/GSDisplayServer.h,
* Source/GSDisplayServer.m: Change signedness of various variables.
* Source/NSPanel.m (-sendEvent:): Remove.
* Source/NSWindow.m (-becomesKeyOnlyIfNeeded): New method.
(-_sendEvent:becomesKeyOnlyIfNeeded:): Remove. Move code ...
(-sendEvent:): ... here. Use -becomesKeyOnlyIfNeeded instead
of the argument.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@20590 72102866-910b-0410-8b05-ffd578937521
2005-01-21 20:39:18 +00:00
|
|
|
NSTiffRead(TIFF *image, NSTiffInfo *info, unsigned char *data)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
int i;
|
2003-06-23 15:50:46 +00:00
|
|
|
unsigned int row, col;
|
1996-08-22 18:51:08 +00:00
|
|
|
int error = 0;
|
2021-11-08 21:46:25 +00:00
|
|
|
uint8_t* outP;
|
|
|
|
uint8_t* buf;
|
|
|
|
uint8_t* raster;
|
1996-08-22 18:51:08 +00:00
|
|
|
NSTiffColormap* map;
|
2015-01-11 21:51:20 +00:00
|
|
|
tmsize_t scan_line_size;
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
if (data == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
map = NULL;
|
2000-04-13 19:23:16 +00:00
|
|
|
if (info->photoInterp == PHOTOMETRIC_PALETTE)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
map = NSTiffGetColormap(image);
|
|
|
|
if (!map)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
scan_line_size = TIFFScanlineSize(image);
|
2000-04-13 19:23:16 +00:00
|
|
|
buf = _TIFFmalloc(scan_line_size);
|
1996-08-22 18:51:08 +00:00
|
|
|
|
2021-11-08 21:46:25 +00:00
|
|
|
raster = (uint8_t *)data;
|
1996-08-22 18:51:08 +00:00
|
|
|
outP = raster;
|
2000-04-13 19:23:16 +00:00
|
|
|
switch (info->photoInterp)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
case PHOTOMETRIC_MINISBLACK:
|
|
|
|
case PHOTOMETRIC_MINISWHITE:
|
2000-04-13 19:23:16 +00:00
|
|
|
if (info->planarConfig == PLANARCONFIG_CONTIG)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
for (row = 0; row < info->height; ++row)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
READ_SCANLINE(0);
|
|
|
|
memcpy(outP, buf, scan_line_size);
|
|
|
|
outP += scan_line_size;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
for (i = 0; i < info->samplesPerPixel; i++)
|
|
|
|
for (row = 0; row < info->height; ++row)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
READ_SCANLINE(i);
|
|
|
|
memcpy(outP, buf, scan_line_size);
|
|
|
|
outP += scan_line_size;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PHOTOMETRIC_PALETTE:
|
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
for (row = 0; row < info->height; ++row)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2021-11-08 21:46:25 +00:00
|
|
|
uint8_t *inP;
|
2000-04-13 19:23:16 +00:00
|
|
|
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++;
|
|
|
|
}
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
free(map);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PHOTOMETRIC_RGB:
|
2000-04-13 19:23:16 +00:00
|
|
|
if (info->planarConfig == PLANARCONFIG_CONTIG)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
for (row = 0; row < info->height; ++row)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
READ_SCANLINE(0);
|
|
|
|
memcpy(outP, buf, scan_line_size);
|
|
|
|
outP += scan_line_size;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
for (i = 0; i < info->samplesPerPixel; i++)
|
|
|
|
for (row = 0; row < info->height; ++row)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2000-04-13 19:23:16 +00:00
|
|
|
READ_SCANLINE(i);
|
|
|
|
memcpy(outP, buf, scan_line_size);
|
|
|
|
outP += scan_line_size;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2003-09-08 02:07:53 +00:00
|
|
|
NSLog(@"Tiff: reading photometric %d not supported", info->photoInterp);
|
2000-04-13 19:23:16 +00:00
|
|
|
error = 1;
|
1996-08-22 18:51:08 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2000-04-13 19:23:16 +00:00
|
|
|
_TIFFfree(buf);
|
1996-08-22 18:51:08 +00:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
#define WRITE_SCANLINE(sample) \
|
|
|
|
if (TIFFWriteScanline(image, buf, row, sample) != 1) { \
|
|
|
|
error = 1; \
|
|
|
|
break; \
|
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
int
|
2005-01-21 21:43 Alexander Malmberg <alexander@malmberg.org>
Various whitespace cleanups, comment type fixes, and changes
to avoid warnings from recent versions of gcc.
* Headers/Additions/GNUstepGUI/GSToolbar.h (-_toolbars): Declare.
* Source/NSWindow+Toolbar.m: Remove conflicting declaration of
[NSToolbar -_toolbars].
* Headers/Additions/GNUstepGUI/GSServicesManager.h,
Source/GSServicesMananger.m (-item2title:, -validateMenuItem:):
Adjust argument types.
* Headers/AppKit/NSMenu.h (-validateMenuItem:): Adjust argument
type.
* Source/NSTextView.m (-sizeToFit): Don't use size uninitialized
if neither resizable flags is set.
(-insertText:): Adjust argument type.
* Headers/AppKit/NSResponder.h, Source/NSResponder.m (-insertText:):
Adjust argument type. Document.
* Headers/AppKit/NSView.h: Change type of ivar _window to NSWindow *.
* Source/GSTitleView.m (-mouseDown:): Always initialize
startWindowOrigin.
* Source/NSApplication.m (-setApplicationIconImage:): Add casts
to avoid warnings.
* Source/NSCell.m (-cellSize): Add default: case.
* Source/NSPasteboard.m
([GSFiltered -pasteboard:provideDataForType:]): Detect and warn if we
can't find a filter that will get us the desired type.
* Source/NSProgressIndicator.m: Comment out unused variable 'images'.
* Source/NSBezierPath.m: Declare GSBezierPath fully before using it.
(-bezierPathByFlatteningPath, -bezierPathByReversingPath): Make sure
variables are always initialized.
* Source/NSMenuView.m,
* Source/NSPrintOperation.m,
* Source/NSSplitView.m,
* Source/NSTableHeaderView.m: Make sure variables are always
initialized.
* Source/NSBox.m,
* Source/NSImageview.m,
* Source/NSText.m,
* Source/NSTextStorage.m: Add missing includes.
* Source/GSKeyBindingTable.m,
* Source/GSLayoutManager.m,
* Source/NSBitmapImageRep+PNM.m,
* Source/NSBundleAdditions.m,
* Source/NSLayoutManager.m,
* Source/nsimage-tiff.h,
* Source/tiff.m,
* Headers/Additions/GNUstepGUI/GSDisplayServer.h,
* Source/GSDisplayServer.m: Change signedness of various variables.
* Source/NSPanel.m (-sendEvent:): Remove.
* Source/NSWindow.m (-becomesKeyOnlyIfNeeded): New method.
(-_sendEvent:becomesKeyOnlyIfNeeded:): Remove. Move code ...
(-sendEvent:): ... here. Use -becomesKeyOnlyIfNeeded instead
of the argument.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@20590 72102866-910b-0410-8b05-ffd578937521
2005-01-21 20:39:18 +00:00
|
|
|
NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
2015-01-23 13:29:38 +00:00
|
|
|
void* buf = (void*)data;
|
2021-11-08 21:46:25 +00:00
|
|
|
uint16_t sample_info[1];
|
1999-12-28 16:02:01 +00:00
|
|
|
int i;
|
2003-06-23 15:50:46 +00:00
|
|
|
unsigned int row;
|
2000-04-13 19:23:16 +00:00
|
|
|
int error = 0;
|
2015-01-11 21:51:20 +00:00
|
|
|
tmsize_t scan_line_size;
|
1999-12-28 16:02:01 +00:00
|
|
|
|
2015-10-10 19:18:33 +00:00
|
|
|
if (info->numImages > 1)
|
|
|
|
{
|
|
|
|
/* Set the page number */
|
|
|
|
TIFFSetField(image, TIFFTAG_PAGENUMBER, info->imageNumber, info->numImages);
|
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
TIFFSetField(image, TIFFTAG_IMAGEWIDTH, info->width);
|
|
|
|
TIFFSetField(image, TIFFTAG_IMAGELENGTH, info->height);
|
2017-04-24 10:42:32 +00:00
|
|
|
if (info->xdpi && info->ydpi)
|
|
|
|
{
|
|
|
|
TIFFSetField(image, TIFFTAG_XRESOLUTION, info->xdpi);
|
|
|
|
TIFFSetField(image, TIFFTAG_YRESOLUTION, info->ydpi);
|
|
|
|
TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, 2);
|
|
|
|
}
|
1999-12-28 16:02:01 +00:00
|
|
|
TIFFSetField(image, TIFFTAG_COMPRESSION, info->compression);
|
2001-09-01 04:20:55 +00:00
|
|
|
if (info->compression == COMPRESSION_JPEG)
|
2015-10-10 19:18:33 +00:00
|
|
|
{
|
|
|
|
TIFFSetField(image, TIFFTAG_JPEGQUALITY, info->quality);
|
|
|
|
}
|
1999-12-28 16:02:01 +00:00
|
|
|
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);
|
|
|
|
|
2001-09-01 20:57:51 +00:00
|
|
|
if (info->assocAlpha)
|
|
|
|
sample_info[0] = EXTRASAMPLE_ASSOCALPHA;
|
|
|
|
else
|
|
|
|
sample_info[0] = EXTRASAMPLE_UNASSALPHA;
|
2001-09-04 03:58:59 +00:00
|
|
|
TIFFSetField(image, TIFFTAG_EXTRASAMPLES, info->extraSamples, sample_info);
|
2011-01-04 14:10:12 +00:00
|
|
|
scan_line_size = TIFFScanlineSize(image);
|
2001-09-01 20:57:51 +00:00
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
switch (info->photoInterp)
|
|
|
|
{
|
|
|
|
case PHOTOMETRIC_MINISBLACK:
|
|
|
|
case PHOTOMETRIC_MINISWHITE:
|
|
|
|
if (info->planarConfig == PLANARCONFIG_CONTIG)
|
|
|
|
{
|
|
|
|
for (row = 0; row < info->height; ++row)
|
|
|
|
{
|
|
|
|
WRITE_SCANLINE(0)
|
2011-01-04 14:10:12 +00:00
|
|
|
buf += scan_line_size;
|
1999-12-28 16:02:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < info->samplesPerPixel; i++)
|
|
|
|
{
|
|
|
|
for (row = 0; row < info->height; ++row)
|
|
|
|
{
|
|
|
|
WRITE_SCANLINE(i)
|
2011-01-04 14:10:12 +00:00
|
|
|
buf += scan_line_size;
|
1999-12-28 16:02:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PHOTOMETRIC_RGB:
|
|
|
|
if (info->planarConfig == PLANARCONFIG_CONTIG)
|
|
|
|
{
|
|
|
|
for (row = 0; row < info->height; ++row)
|
|
|
|
{
|
|
|
|
WRITE_SCANLINE(0)
|
2011-01-04 14:10:12 +00:00
|
|
|
buf += scan_line_size;
|
1999-12-28 16:02:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < info->samplesPerPixel; i++)
|
|
|
|
{
|
|
|
|
for (row = 0; row < info->height; ++row)
|
|
|
|
{
|
|
|
|
WRITE_SCANLINE(i)
|
2011-01-04 14:10:12 +00:00
|
|
|
buf += scan_line_size;
|
1999-12-28 16:02:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-09-08 02:07:53 +00:00
|
|
|
NSLog(@"Tiff: photometric %d for image %s not supported",
|
2000-04-13 19:23:16 +00:00
|
|
|
info->photoInterp, TIFFFileName(image));
|
|
|
|
return -1;
|
1999-12-28 16:02:01 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-10-10 19:18:33 +00:00
|
|
|
|
|
|
|
// Write out the directory as there may be more images comming
|
|
|
|
TIFFWriteDirectory(image);
|
|
|
|
TIFFFlush(image);
|
|
|
|
|
2003-09-08 02:07:53 +00:00
|
|
|
return error;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* 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)
|
|
|
|
{
|
2003-06-23 15:50:46 +00:00
|
|
|
register unsigned int i;
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2011-02-28 15:43:25 +00:00
|
|
|
map = malloc(sizeof(NSTiffColormap));
|
1996-08-22 18:51:08 +00:00
|
|
|
map->size = 1 << info->bitsPerSample;
|
|
|
|
|
|
|
|
if (!TIFFGetField(image, TIFFTAG_COLORMAP,
|
|
|
|
&map->red, &map->green, &map->blue))
|
|
|
|
{
|
|
|
|
TIFFError(TIFFFileName(image), "Missing required \"Colormap\" tag");
|
2011-02-28 15:43:25 +00:00
|
|
|
free(map);
|
1996-08-22 18:51:08 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (CheckAndCorrectColormap(map) == 8)
|
|
|
|
TIFFWarning(TIFFFileName(image), "Assuming 8-bit colormap");
|
|
|
|
|
|
|
|
free(info);
|
|
|
|
return map;
|
|
|
|
}
|
2000-09-27 15:16:42 +00:00
|
|
|
|
Change Log
Mon. 20-Nov-2006 Mark Tracy <tracy454 at concentric dot net>
Many changes related to bitmap images
1. NSBitmapImateRep attribute global strings were not defined
Fix: add definitions to externs.h, and declarations to NSBitmapImageRep.h
Comment: Two strings defined in Cocoa were commented out: NSImageColorSyncData
is proprietary to Apple, and NSImageEXIFData has no support elsewhere in
GNUstep. I propose adding GSImageICCProfileData if and when color management
is added to GNUstep.
2. LZW compression in TIFF was disabled for lack of a test of its availability
Fix: Implement NSTiffIsCodecConfigured(codec) in tiff.m
Comment: As of libtiff-3.7.0, there is a function call in the API to test
availability at runtime. For libtiff-3.6.0 (earlier?) there are macros
#defined in tiffconf.h. The implementation check the library version at
compile time, and uses one of the two methods. I have not tested the
second method for lack of an installation of an old libtiff.
3. -canCompressUsing: relied on a static list of capabilities
Fix: Use the new NSTiffIsCodecConfigured(codec) in NSBitmapImageRep.m
Comment: The static list could be wrong, as it was on my system. Also
eliminate the supports_lzw_compression flag.
4. +getTIFFCompressionTypes:count: relied on a static list of compressors.
Fix: Use the new NSTiffIsCodecConfigured(codec) in NSBitmapImageRep.m
Comment: Compares GNUstep supported compressors against actual availability.
Also change the private instance methods _localFromCompressionType and
_compressionTypeFromLocal to private class methods so that they can be used
in -initWithTIFFImage:number: and -TIFFRepresentationUsingCompression:factor:
and +getTIFFCompressionTypes:count: This is probably a clumsy implementation
but it works.
5. -setProperty:toValue: and -valueForProperty: were not implemented
Fix: Add a new instance variable NSMutableDictionary * _properties to
NSBitmapImageRep.h and implemented accessors in NSBitmapImageRep.m. Patch
-_initFromTIFFImage to set compression type and factor in _properties.
Comment: This feature is used to pass options to and from JPEG, PNG, TIFF, and
GIF in Cocoa, although the docs are kind of vague. In one case the Cocoa docs
said the properties were set when reading a TIFF, but the implementation
didn't; I chose to implement the docs. Cocoa does use properties when
exporting bitmaps, so I implemented that.
6. Checked and updated NSBitmapImageFileType in NSBitmapImageRep.h
Fix: confirmed the enumeration values against Cocoa, and added
NSJPEG2000FileType = 5
Comment: JPEG-2000 is not implemented, just reserved a space for it.
7. -representationUsingType:properties: was not implemented
Fix: Implement export of TIFF, JPEG, GIF and PNG in NSBitmapImage.m
Comment: See the change notes for JPEG, GIF, and PNG for more. BMP and JPEG-2000
are not implemented; they just log a message to that effect. As apparently
Cocoa does it this way, if you pass nil for properties, it falls back to
the internal _properties, and if that is empty, there are some safe defaults.
8. +representationfOfImageRepsInArray:UsingType:properties: was not implemented
Fix: Partially implement in NSBitmapImageRep.m
Comment: I just stole the incomplete code from
+TIFFRepresentationOfImageRepsInArray: since I have yet to find an explanation
of how this really ought to work.
9. JPEG export didn't handle alpha channel, properties or errors.
Fix: Add -_JPEGRepresentationWithProperties:errorMessage: to
NSBitmapImageRep+JPEG.h and greatly rework Nicolas Roard's code in
NSBitmapImageRep+JPEG.m. Patch -_initBitmapFromJPEG:errorMessage to
write properties.
Comment: Major rewrite of Nicolas Roard's JPEG export code.
To do: Support for planar bitmaps and support for colorspaces other than
RGB(A).
10. PNG export not implemented
Fix: Add -_PNGRepresentationWithProperties: to
NSBitmapImageRep+PNG.h and implement NSBitmapImageRep+PNG.m
Comment: No support yet for planar bitmaps. Only supports
NS*WhiteColorSpace and NS*RGBColorSpace. Does support alpha. Support for
reading and writing NSImageGamma is experimental. In keeping with Cocoa,
the property NSImageGamma ranges from 0.0 to 1.0; representing the range
of minimum supported gamma to maximum supported gamma, in this case 1.0
to 2.5. This is in contrast to GNUstep where by convention the property
would range from 0.0 to 255.0.
To do: proper error message support
11. GIF export not implemented
Fix: Add -_GIFRepresentationWithPropterties:errorMessage: to
NSBitmapImageRep+GIF.h and implement in NSBitmapImageRep+GIF.m
Comments: Supports only RGB(A) colorspaces, but ignores alpha. Supports
planar or interleaved bitmaps. Supports properties NSImageRGBColorTable.
12. -_initBitmapFromGIF:errorMessage: did not support transparency
Fix: Don't ignore control blocks in NSBitmapImageRep+GIF.m; check for
transparency.
Comment: If a transparent color is found, it adds an alpha channel to the
bitmap. Also, save the color table in properties.
13. -_initBitmapFromGIF:errorMessage: would show the last image in a
multi-image GIF file
Fix: Break the parsing loop after the first image in NSBitmapImageRep+GIF.m
Comment: Also check for frame duration, and set that property. There is not
yet any support for animated GIF. This will require some additional
infrastructure, and I won't do it unless asked.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@24140 72102866-910b-0410-8b05-ffd578937521
2006-11-21 06:36:26 +00:00
|
|
|
int NSTiffIsCodecConfigured(unsigned int codec)
|
|
|
|
{
|
|
|
|
#if (TIFFLIB_VERSION >= 20041016)
|
2008-06-12 14:09:48 +00:00
|
|
|
// starting with version 3.7.0 we can ask libtiff what it is configured to do
|
Change Log
Mon. 20-Nov-2006 Mark Tracy <tracy454 at concentric dot net>
Many changes related to bitmap images
1. NSBitmapImateRep attribute global strings were not defined
Fix: add definitions to externs.h, and declarations to NSBitmapImageRep.h
Comment: Two strings defined in Cocoa were commented out: NSImageColorSyncData
is proprietary to Apple, and NSImageEXIFData has no support elsewhere in
GNUstep. I propose adding GSImageICCProfileData if and when color management
is added to GNUstep.
2. LZW compression in TIFF was disabled for lack of a test of its availability
Fix: Implement NSTiffIsCodecConfigured(codec) in tiff.m
Comment: As of libtiff-3.7.0, there is a function call in the API to test
availability at runtime. For libtiff-3.6.0 (earlier?) there are macros
#defined in tiffconf.h. The implementation check the library version at
compile time, and uses one of the two methods. I have not tested the
second method for lack of an installation of an old libtiff.
3. -canCompressUsing: relied on a static list of capabilities
Fix: Use the new NSTiffIsCodecConfigured(codec) in NSBitmapImageRep.m
Comment: The static list could be wrong, as it was on my system. Also
eliminate the supports_lzw_compression flag.
4. +getTIFFCompressionTypes:count: relied on a static list of compressors.
Fix: Use the new NSTiffIsCodecConfigured(codec) in NSBitmapImageRep.m
Comment: Compares GNUstep supported compressors against actual availability.
Also change the private instance methods _localFromCompressionType and
_compressionTypeFromLocal to private class methods so that they can be used
in -initWithTIFFImage:number: and -TIFFRepresentationUsingCompression:factor:
and +getTIFFCompressionTypes:count: This is probably a clumsy implementation
but it works.
5. -setProperty:toValue: and -valueForProperty: were not implemented
Fix: Add a new instance variable NSMutableDictionary * _properties to
NSBitmapImageRep.h and implemented accessors in NSBitmapImageRep.m. Patch
-_initFromTIFFImage to set compression type and factor in _properties.
Comment: This feature is used to pass options to and from JPEG, PNG, TIFF, and
GIF in Cocoa, although the docs are kind of vague. In one case the Cocoa docs
said the properties were set when reading a TIFF, but the implementation
didn't; I chose to implement the docs. Cocoa does use properties when
exporting bitmaps, so I implemented that.
6. Checked and updated NSBitmapImageFileType in NSBitmapImageRep.h
Fix: confirmed the enumeration values against Cocoa, and added
NSJPEG2000FileType = 5
Comment: JPEG-2000 is not implemented, just reserved a space for it.
7. -representationUsingType:properties: was not implemented
Fix: Implement export of TIFF, JPEG, GIF and PNG in NSBitmapImage.m
Comment: See the change notes for JPEG, GIF, and PNG for more. BMP and JPEG-2000
are not implemented; they just log a message to that effect. As apparently
Cocoa does it this way, if you pass nil for properties, it falls back to
the internal _properties, and if that is empty, there are some safe defaults.
8. +representationfOfImageRepsInArray:UsingType:properties: was not implemented
Fix: Partially implement in NSBitmapImageRep.m
Comment: I just stole the incomplete code from
+TIFFRepresentationOfImageRepsInArray: since I have yet to find an explanation
of how this really ought to work.
9. JPEG export didn't handle alpha channel, properties or errors.
Fix: Add -_JPEGRepresentationWithProperties:errorMessage: to
NSBitmapImageRep+JPEG.h and greatly rework Nicolas Roard's code in
NSBitmapImageRep+JPEG.m. Patch -_initBitmapFromJPEG:errorMessage to
write properties.
Comment: Major rewrite of Nicolas Roard's JPEG export code.
To do: Support for planar bitmaps and support for colorspaces other than
RGB(A).
10. PNG export not implemented
Fix: Add -_PNGRepresentationWithProperties: to
NSBitmapImageRep+PNG.h and implement NSBitmapImageRep+PNG.m
Comment: No support yet for planar bitmaps. Only supports
NS*WhiteColorSpace and NS*RGBColorSpace. Does support alpha. Support for
reading and writing NSImageGamma is experimental. In keeping with Cocoa,
the property NSImageGamma ranges from 0.0 to 1.0; representing the range
of minimum supported gamma to maximum supported gamma, in this case 1.0
to 2.5. This is in contrast to GNUstep where by convention the property
would range from 0.0 to 255.0.
To do: proper error message support
11. GIF export not implemented
Fix: Add -_GIFRepresentationWithPropterties:errorMessage: to
NSBitmapImageRep+GIF.h and implement in NSBitmapImageRep+GIF.m
Comments: Supports only RGB(A) colorspaces, but ignores alpha. Supports
planar or interleaved bitmaps. Supports properties NSImageRGBColorTable.
12. -_initBitmapFromGIF:errorMessage: did not support transparency
Fix: Don't ignore control blocks in NSBitmapImageRep+GIF.m; check for
transparency.
Comment: If a transparent color is found, it adds an alpha channel to the
bitmap. Also, save the color table in properties.
13. -_initBitmapFromGIF:errorMessage: would show the last image in a
multi-image GIF file
Fix: Break the parsing loop after the first image in NSBitmapImageRep+GIF.m
Comment: Also check for frame duration, and set that property. There is not
yet any support for animated GIF. This will require some additional
infrastructure, and I won't do it unless asked.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@24140 72102866-910b-0410-8b05-ffd578937521
2006-11-21 06:36:26 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2000-09-27 15:16:42 +00:00
|
|
|
|