* Source/nsimage-tiff.h: Correct field types.

* Source/NSImage.m (-TIFFRepresentation)
        (TIFFRepresentationUsingCompression:factor:): Pass on bitmaps
only.
        * Source/NSBitmapImageRep.m: Implement methods to generate tiff
        for multiple bitmaps.
        * Source/tiff.m: Fix long standing bug in TiffHandleSeek.
        In NSTiffWrite write image tiff directory to allow for multiple
        images.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@39050 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fredkiefer 2015-10-10 19:18:33 +00:00
parent 95dbc26988
commit b8fb4e24b1
5 changed files with 377 additions and 160 deletions

View file

@ -1,3 +1,14 @@
2015-10-10 Fred Kiefer <FredKiefer@gmx.de>
* Source/nsimage-tiff.h: Correct field types.
* Source/NSImage.m (-TIFFRepresentation)
(TIFFRepresentationUsingCompression:factor:): Pass on bitmaps only.
* Source/NSBitmapImageRep.m: Implement methods to generate tiff
for multiple bitmaps.
* Source/tiff.m: Fix long standing bug in TiffHandleSeek.
In NSTiffWrite write image tiff directory to allow for multiple
images.
2015-10-09 Fred Kiefer <FredKiefer@gmx.de> 2015-10-09 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSGraphicsContext.m (-initWithContextInfo:): Move the * Source/NSGraphicsContext.m (-initWithContextInfo:): Move the

View file

@ -61,7 +61,13 @@
/* Backend methods (optional) */ /* Backend methods (optional) */
@interface NSBitmapImageRep (GSPrivate) @interface NSBitmapImageRep (GSPrivate)
// GNUstep extension // GNUstep extension
- _initFromTIFFImage: (TIFF *)image number: (int)imageNumber; + (BOOL) _bitmapIsTIFF: (NSData *)data;
+ (NSArray*) _imageRepsWithTIFFData: (NSData *)imageData;
- (NSBitmapImageRep *) _initBitmapFromTIFF: (NSData *)imageData;
- (NSBitmapImageRep *) _initFromTIFFImage: (TIFF *)image number: (int)imageNumber;
- (void) _fillTIFFInfo: (NSTiffInfo*)info
usingCompression: (NSTIFFCompression)type
factor: (float)factor;
// Internal // Internal
+ (int) _localFromCompressionType: (NSTIFFCompression)type; + (int) _localFromCompressionType: (NSTIFFCompression)type;
@ -98,39 +104,36 @@
/** Returns YES if the image stored in data can be read and decoded */ /** Returns YES if the image stored in data can be read and decoded */
+ (BOOL) canInitWithData: (NSData *)data + (BOOL) canInitWithData: (NSData *)data
{ {
TIFF *image = NULL;
if (data == nil) if (data == nil)
{ {
return NO; return NO;
} }
#if HAVE_LIBPNG
if ([self _bitmapIsPNG: data]) if ([self _bitmapIsPNG: data])
return YES; return YES;
#endif
if ([self _bitmapIsPNM: data]) if ([self _bitmapIsPNM: data])
return YES; return YES;
#if HAVE_LIBJPEG
if ([self _bitmapIsJPEG: data]) if ([self _bitmapIsJPEG: data])
return YES; return YES;
#endif
#if HAVE_LIBUNGIF || HAVE_LIBGIF
if ([self _bitmapIsGIF: data]) if ([self _bitmapIsGIF: data])
return YES; return YES;
#endif
if ([self _bitmapIsICNS: data]) if ([self _bitmapIsICNS: data])
return YES; return YES;
image = NSTiffOpenDataRead ((char *)[data bytes], [data length]); if ([self _bitmapIsTIFF: data])
return YES;
if (image != NULL) return NO;
{
NSTiffClose (image);
return YES;
}
else
{
return NO;
}
} }
/** Returns a list of image filename extensions that are understood by /** Returns a list of image filename extensions that are understood by
@ -189,10 +192,6 @@
*/ */
+ (NSArray*) imageRepsWithData: (NSData *)imageData + (NSArray*) imageRepsWithData: (NSData *)imageData
{ {
int i, images;
TIFF *image;
NSMutableArray *array;
if (imageData == nil) if (imageData == nil)
{ {
NSLog(@"NSBitmapImageRep: nil image data"); NSLog(@"NSBitmapImageRep: nil image data");
@ -259,36 +258,20 @@
return [self _imageRepsWithICNSData: imageData]; return [self _imageRepsWithICNSData: imageData];
} }
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]); if ([self _bitmapIsTIFF: imageData])
if (image == NULL)
{ {
NSLog(@"NSBitmapImageRep: unable to parse TIFF data"); return [self _imageRepsWithTIFFData: imageData];
return [NSArray array];
} }
images = NSTiffGetImageCount(image); NSLog(@"NSBitmapImageRep: unable to parse bitmap image data");
NSDebugLLog(@"NSImage", @"Image contains %d directories", images); return [NSArray array];
array = [NSMutableArray arrayWithCapacity: images];
for (i = 0; i < images; i++)
{
NSBitmapImageRep* imageRep;
imageRep = [[self alloc] _initFromTIFFImage: image number: i];
if (imageRep)
{
[array addObject: imageRep];
RELEASE(imageRep);
}
}
NSTiffClose(image);
return array;
} }
/** Loads only the default (first) image from the image contained in /** Loads only the default (first) image from the image contained in
data. */ data. */
- (id) initWithData: (NSData *)imageData - (id) initWithData: (NSData *)imageData
{ {
TIFF *image; Class class;
if (imageData == nil) if (imageData == nil)
{ {
@ -296,36 +279,30 @@
return nil; return nil;
} }
if ([object_getClass(self) _bitmapIsPNG: imageData]) class = [self class];
if ([class _bitmapIsPNG: imageData])
return [self _initBitmapFromPNG: imageData]; return [self _initBitmapFromPNG: imageData];
if ([object_getClass(self) _bitmapIsPNM: imageData]) if ([class _bitmapIsPNM: imageData])
return [self _initBitmapFromPNM: imageData return [self _initBitmapFromPNM: imageData
errorMessage: NULL]; errorMessage: NULL];
if ([object_getClass(self) _bitmapIsJPEG: imageData]) if ([class _bitmapIsJPEG: imageData])
return [self _initBitmapFromJPEG: imageData return [self _initBitmapFromJPEG: imageData
errorMessage: NULL]; errorMessage: NULL];
if ([object_getClass(self) _bitmapIsGIF: imageData]) if ([class _bitmapIsGIF: imageData])
return [self _initBitmapFromGIF: imageData return [self _initBitmapFromGIF: imageData
errorMessage: NULL]; errorMessage: NULL];
if ([object_getClass(self) _bitmapIsICNS: imageData]) if ([class _bitmapIsICNS: imageData])
return [self _initBitmapFromICNS: imageData]; return [self _initBitmapFromICNS: imageData];
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]); if ([class _bitmapIsTIFF: imageData])
if (image == NULL) return [self _initBitmapFromTIFF: imageData];
{
RELEASE(self);
NSLog(@"Tiff read invalid TIFF info from data");
return nil;
}
[self _initFromTIFFImage: image number: -1]; DESTROY(self);
NSTiffClose(image); return nil;
return self;
} }
/** Initialize with bitmap data from a rect within the focused view */ /** Initialize with bitmap data from a rect within the focused view */
@ -861,7 +838,7 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
} }
line_offset = _bytesPerRow * y; line_offset = _bytesPerRow * y;
if(_isPlanar) if (_isPlanar)
{ {
if (_bitsPerSample == 8) if (_bitsPerSample == 8)
{ {
@ -1393,48 +1370,89 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
// //
/** Produces an NSData object containing a TIFF representation of all /** Produces an NSData object containing a TIFF representation of all
the images stored in anArray. BUGS: Currently this only works if the the images stored in anArray. BUGS: Currently this only works if the
images are NSBitmapImageRep objects, and it only creates an TIFF from the images are NSBitmapImageRep objects. */
first image in the array. */
+ (NSData*) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray + (NSData*) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray
{ {
//FIXME: This only outputs one of the ImageReps
NSEnumerator *enumerator = [anArray objectEnumerator]; NSEnumerator *enumerator = [anArray objectEnumerator];
NSImageRep *rep; NSImageRep *rep;
TIFF *image;
NSTiffInfo info;
char *bytes = 0;
long length = 0;
int num = 0;
image = NSTiffOpenDataWrite(&bytes, &length);
if (image == 0)
{
[NSException raise: NSTIFFException
format: @"Opening data stream for writting"];
}
while ((rep = [enumerator nextObject]) != nil) while ((rep = [enumerator nextObject]) != nil)
{ {
if ([rep isKindOfClass: self]) if ([rep isKindOfClass: self])
{ {
return [(NSBitmapImageRep*)rep TIFFRepresentation]; NSTIFFCompression compression;
float factor;
NSBitmapImageRep *bitmap = (NSBitmapImageRep*)rep;
[bitmap getCompression: &compression
factor: &factor];
[bitmap _fillTIFFInfo: &info
usingCompression: compression
factor: factor];
info.imageNumber = num++;
info.numImages = [anArray count];
info.subfileType = FILETYPE_PAGE;
if (NSTiffWrite(image, &info, [bitmap bitmapData]) != 0)
{
[NSException raise: NSTIFFException format: @"Writing data"];
}
} }
} }
return nil; NSTiffClose(image);
return [NSData dataWithBytesNoCopy: bytes length: length];
} }
/** Produces an NSData object containing a TIFF representation of all /** Produces an NSData object containing a TIFF representation of all
the images stored in anArray. The image is compressed according to the images stored in anArray. The image is compressed according to
the compression type and factor. BUGS: Currently this only works if the compression type and factor. BUGS: Currently this only works if
the images are NSBitmapImageRep objects, and it only creates an the images are NSBitmapImageRep objects. */
TIFF from the first image in the array. */
+ (NSData*) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray + (NSData*) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray
usingCompression: (NSTIFFCompression)type usingCompression: (NSTIFFCompression)compression
factor: (float)factor factor: (float)factor
{ {
//FIXME: This only outputs one of the ImageReps
NSEnumerator *enumerator = [anArray objectEnumerator]; NSEnumerator *enumerator = [anArray objectEnumerator];
NSImageRep *rep; NSImageRep *rep;
NSTiffInfo info;
TIFF *image;
char *bytes = 0;
long length = 0;
image = NSTiffOpenDataWrite(&bytes, &length);
if (image == 0)
{
[NSException raise: NSTIFFException
format: @"Opening data stream for writting"];
}
while ((rep = [enumerator nextObject]) != nil) while ((rep = [enumerator nextObject]) != nil)
{ {
if ([rep isKindOfClass: self]) if ([rep isKindOfClass: self])
{ {
return [(NSBitmapImageRep*)rep TIFFRepresentationUsingCompression: type [(NSBitmapImageRep*)rep _fillTIFFInfo: &info
factor: factor]; usingCompression: compression
factor: factor];
if (NSTiffWrite(image, &info, [(NSBitmapImageRep*)rep bitmapData]) != 0)
{
[NSException raise: NSTIFFException format: @"Writing data"];
}
} }
} }
return nil; NSTiffClose(image);
return [NSData dataWithBytesNoCopy: bytes length: length];
} }
/** Returns an NSData object containing a TIFF representation of the /** Returns an NSData object containing a TIFF representation of the
@ -1452,7 +1470,7 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
/** Returns an NSData object containing a TIFF representation of the /** Returns an NSData object containing a TIFF representation of the
receiver. The TIFF data is compressed using compresssion type receiver. The TIFF data is compressed using compresssion type
and factor. */ and factor. */
- (NSData*) TIFFRepresentationUsingCompression: (NSTIFFCompression)type - (NSData*) TIFFRepresentationUsingCompression: (NSTIFFCompression)compression
factor: (float)factor factor: (float)factor
{ {
NSTiffInfo info; NSTiffInfo info;
@ -1460,56 +1478,16 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
char *bytes = 0; char *bytes = 0;
long length = 0; long length = 0;
info.imageNumber = 0;
info.subfileType = 255;
info.width = _pixelsWide;
info.height = _pixelsHigh;
info.bitsPerSample = _bitsPerSample;
info.samplesPerPixel = _numColors;
if ([self canBeCompressedUsing: type] == NO)
{
type = NSTIFFCompressionNone;
factor = 0;
}
if (_isPlanar)
info.planarConfig = PLANARCONFIG_SEPARATE;
else
info.planarConfig = PLANARCONFIG_CONTIG;
if ([_colorSpace isEqual: NSDeviceRGBColorSpace]
|| [_colorSpace isEqual: NSCalibratedRGBColorSpace])
info.photoInterp = PHOTOMETRIC_RGB;
else if ([_colorSpace isEqual: NSDeviceWhiteColorSpace]
|| [_colorSpace isEqual: NSCalibratedWhiteColorSpace])
info.photoInterp = PHOTOMETRIC_MINISBLACK;
else if ([_colorSpace isEqual: NSDeviceBlackColorSpace]
|| [_colorSpace isEqual: NSCalibratedBlackColorSpace])
info.photoInterp = PHOTOMETRIC_MINISWHITE;
else
{
NSWarnMLog(@"Unknown colorspace %@.", _colorSpace);
info.photoInterp = PHOTOMETRIC_RGB;
}
info.extraSamples = (_hasAlpha) ? 1 : 0;
info.assocAlpha = (_format & NSAlphaNonpremultipliedBitmapFormat) ? 0 : 1;
info.compression = [NSBitmapImageRep _localFromCompressionType: type];
if (factor < 0)
factor = 0;
if (factor > 1)
factor = 1;
info.quality = factor * 100;
info.numImages = 1;
info.error = 0;
image = NSTiffOpenDataWrite(&bytes, &length); image = NSTiffOpenDataWrite(&bytes, &length);
if (image == 0) if (image == 0)
{ {
[NSException raise: NSTIFFException [NSException raise: NSTIFFException
format: @"Opening data stream for writting"]; format: @"Opening data stream for writting"];
} }
[self _fillTIFFInfo: &info
usingCompression: compression
factor: factor];
if (NSTiffWrite(image, &info, [self bitmapData]) != 0) if (NSTiffWrite(image, &info, [self bitmapData]) != 0)
{ {
[NSException raise: NSTIFFException format: @"Writing data"]; [NSException raise: NSTIFFException format: @"Writing data"];
@ -1533,13 +1511,35 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
NSEnumerator *enumerator = [imageReps objectEnumerator]; NSEnumerator *enumerator = [imageReps objectEnumerator];
NSImageRep *rep; NSImageRep *rep;
while ((rep = [enumerator nextObject]) != nil) if (storageType == NSTIFFFileType)
{ {
if ([rep isKindOfClass: self]) NSNumber *comp_property = [properties objectForKey: NSImageCompressionMethod];
NSNumber *factor_property = [properties objectForKey: NSImageCompressionFactor];
if ((comp_property != nil) && (factor_property != nil))
{ {
return [(NSBitmapImageRep*)rep representationUsingType: storageType float factor = [factor_property floatValue];
properties: properties]; NSTIFFCompression compression = [comp_property unsignedShortValue];
}
return [self TIFFRepresentationOfImageRepsInArray: imageReps
usingCompression: compression
factor: factor];
}
else
{
return [self TIFFRepresentationOfImageRepsInArray: imageReps];
}
}
else
{
while ((rep = [enumerator nextObject]) != nil)
{
if ([rep isKindOfClass: self])
{
return [(NSBitmapImageRep*)rep representationUsingType: storageType
properties: properties];
}
}
} }
return nil; return nil;
@ -1562,7 +1562,7 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
{ {
case NSTIFFFileType: case NSTIFFFileType:
{ {
NSNumber * property; NSNumber *property;
float factor = _comp_factor; float factor = _comp_factor;
NSTIFFCompression compression = _compression; NSTIFFCompression compression = _compression;
if ((property = [__properties objectForKey: NSImageCompressionMethod])) if ((property = [__properties objectForKey: NSImageCompressionMethod]))
@ -1866,10 +1866,71 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
return NSTIFFCompressionNone; return NSTIFFCompressionNone;
} }
+ (BOOL) _bitmapIsTIFF: (NSData *)data
{
TIFF *image = NSTiffOpenDataRead((char *)[data bytes], [data length]);
if (image != NULL)
{
NSTiffClose(image);
return YES;
}
else
{
return NO;
}
}
+ (NSArray*) _imageRepsWithTIFFData: (NSData *)imageData
{
int i, images;
TIFF *image;
NSMutableArray *array;
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
if (image == NULL)
{
NSLog(@"NSBitmapImageRep: unable to parse TIFF data");
return [NSArray array];
}
images = NSTiffGetImageCount(image);
NSDebugLLog(@"NSImage", @"Image contains %d directories", images);
array = [NSMutableArray arrayWithCapacity: images];
for (i = 0; i < images; i++)
{
NSBitmapImageRep* imageRep;
imageRep = [[self alloc] _initFromTIFFImage: image number: i];
if (imageRep)
{
[array addObject: imageRep];
RELEASE(imageRep);
}
}
NSTiffClose(image);
return array;
}
- (NSBitmapImageRep *) _initBitmapFromTIFF: (NSData *)imageData
{
TIFF *image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
if (image == NULL)
{
RELEASE(self);
NSLog(@"Tiff read invalid TIFF info from data");
return nil;
}
[self _initFromTIFFImage: image number: -1];
NSTiffClose(image);
return self;
}
/* Given a TIFF image (from the libtiff library), load the image information /* Given a TIFF image (from the libtiff library), load the image information
into our data structure. Reads the specified image. */ into our data structure. Reads the specified image. */
- _initFromTIFFImage: (TIFF *)image number: (int)imageNumber - (NSBitmapImageRep *) _initFromTIFFImage: (TIFF *)image number: (int)imageNumber
{ {
NSString* space; NSString* space;
NSTiffInfo* info; NSTiffInfo* info;
@ -1940,6 +2001,56 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
return self; return self;
} }
- (void) _fillTIFFInfo: (NSTiffInfo*)info
usingCompression: (NSTIFFCompression)type
factor: (float)factor
{
info->numImages = 1;
info->imageNumber = 0;
info->subfileType = 255;
info->width = _pixelsWide;
info->height = _pixelsHigh;
info->bitsPerSample = _bitsPerSample;
info->samplesPerPixel = _numColors;
if (_isPlanar)
info->planarConfig = PLANARCONFIG_SEPARATE;
else
info->planarConfig = PLANARCONFIG_CONTIG;
if ([_colorSpace isEqual: NSDeviceRGBColorSpace]
|| [_colorSpace isEqual: NSCalibratedRGBColorSpace])
info->photoInterp = PHOTOMETRIC_RGB;
else if ([_colorSpace isEqual: NSDeviceWhiteColorSpace]
|| [_colorSpace isEqual: NSCalibratedWhiteColorSpace])
info->photoInterp = PHOTOMETRIC_MINISBLACK;
else if ([_colorSpace isEqual: NSDeviceBlackColorSpace]
|| [_colorSpace isEqual: NSCalibratedBlackColorSpace])
info->photoInterp = PHOTOMETRIC_MINISWHITE;
else
{
NSWarnMLog(@"Unknown colorspace %@.", _colorSpace);
info->photoInterp = PHOTOMETRIC_RGB;
}
info->extraSamples = (_hasAlpha) ? 1 : 0;
info->assocAlpha = (_format & NSAlphaNonpremultipliedBitmapFormat) ? 0 : 1;
if ([self canBeCompressedUsing: type] == NO)
{
type = NSTIFFCompressionNone;
factor = 0;
}
info->compression = [NSBitmapImageRep _localFromCompressionType: type];
if (factor < 0)
factor = 0;
if (factor > 1)
factor = 1;
info->quality = factor * 100;
info->error = 0;
}
- (void) _premultiply - (void) _premultiply
{ {
NSInteger x, y; NSInteger x, y;
@ -1968,25 +2079,65 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
if (_bitsPerSample == 8) if (_bitsPerSample == 8)
{ {
NSUInteger a; if (!_isPlanar)
for (y = 0; y < _pixelsHigh; y++)
{ {
for (x = 0; x < _pixelsWide; x++) // Optimize for the most common case
{ NSUInteger a;
//[self getPixel: pixelData atX: x y: y]; NSInteger offset;
getP(self, getPSel, pixelData, x, y); NSInteger line_offset;
a = pixelData[ai];
if (a != 255)
{
for (i = start; i < end; i++)
{
NSUInteger t = a * pixelData[i] + 0x80;
pixelData[i] = ((t >> 8) + t) >> 8; for (y = 0; y < _pixelsHigh; y++)
{
line_offset = _bytesPerRow * y + _bitsPerPixel / 8;
for (x = 0; x < _pixelsWide; x++)
{
offset = x + line_offset;
a = _imagePlanes[0][offset + ai];
if ((a != 0) && (a != 255))
{
for (i = start; i < end; i++)
{
NSUInteger v = _imagePlanes[0][offset + i];
NSUInteger c;
c = (v * 255) / a;
if (c >= 255)
{
v = 255;
}
else
{
v = c;
}
_imagePlanes[0][offset + i] = v;
}
}
}
}
}
else
{
NSUInteger a;
for (y = 0; y < _pixelsHigh; y++)
{
for (x = 0; x < _pixelsWide; x++)
{
//[self getPixel: pixelData atX: x y: y];
getP(self, getPSel, pixelData, x, y);
a = pixelData[ai];
if (a != 255)
{
for (i = start; i < end; i++)
{
NSUInteger t = a * pixelData[i] + 0x80;
pixelData[i] = ((t >> 8) + t) >> 8;
}
//[self setPixel: pixelData atX: x y: y];
setP(self, setPSel, pixelData, x, y);
} }
//[self setPixel: pixelData atX: x y: y];
setP(self, setPSel, pixelData, x, y);
} }
} }
} }
@ -2045,33 +2196,74 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
if (_bitsPerSample == 8) if (_bitsPerSample == 8)
{ {
NSUInteger a; if (!_isPlanar)
for (y = 0; y < _pixelsHigh; y++)
{ {
for (x = 0; x < _pixelsWide; x++) // Optimize for the most common case
NSUInteger a;
NSInteger offset;
NSInteger line_offset;
for (y = 0; y < _pixelsHigh; y++)
{ {
//[self getPixel: pixelData atX: x y: y]; line_offset = _bytesPerRow * y + _bitsPerPixel / 8;
getP(self, getPSel, pixelData, x, y); for (x = 0; x < _pixelsWide; x++)
a = pixelData[ai];
if ((a != 0) && (a != 255))
{ {
for (i = start; i < end; i++) offset = x + line_offset;
a = _imagePlanes[0][offset + ai];
if (a != 255)
{ {
NSUInteger c; if (a == 0)
c = (pixelData[i] * 255) / a;
if (c >= 255)
{ {
pixelData[i] = 255; for (i = start; i < end; i++)
{
_imagePlanes[0][offset + i] = 0;
}
} }
else else
{ {
pixelData[i] = c; for (i = start; i < end; i++)
{
NSUInteger v = _imagePlanes[0][offset + i];
NSUInteger t = a * v + 0x80;
v = ((t >> 8) + t) >> 8;
_imagePlanes[0][offset + i] = v;
}
} }
} }
//[self setPixel: pixelData atX: x y: y]; }
setP(self, setPSel, pixelData, x, y); }
}
else
{
NSUInteger a;
for (y = 0; y < _pixelsHigh; y++)
{
for (x = 0; x < _pixelsWide; x++)
{
//[self getPixel: pixelData atX: x y: y];
getP(self, getPSel, pixelData, x, y);
a = pixelData[ai];
if ((a != 0) && (a != 255))
{
for (i = start; i < end; i++)
{
NSUInteger c;
c = (pixelData[i] * 255) / a;
if (c >= 255)
{
pixelData[i] = 255;
}
else
{
pixelData[i] = c;
}
}
//[self setPixel: pixelData atX: x y: y];
setP(self, setPSel, pixelData, x, y);
}
} }
} }
} }

View file

@ -1518,7 +1518,7 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
NSData *data; NSData *data;
// As a result of using bitmap representations, new drawing wont show on the tiff data. // As a result of using bitmap representations, new drawing wont show on the tiff data.
data = [bitmapClass TIFFRepresentationOfImageRepsInArray: [self representations]]; data = [bitmapClass TIFFRepresentationOfImageRepsInArray: [self _representationsWithCachedImages: NO]];
if (!data) if (!data)
{ {
@ -1547,7 +1547,7 @@ static NSSize GSResolutionOfImageRep(NSImageRep *rep)
NSData *data; NSData *data;
// As a result of using bitmap representations, new drawing wont show on the tiff data. // As a result of using bitmap representations, new drawing wont show on the tiff data.
data = [bitmapClass TIFFRepresentationOfImageRepsInArray: [self representations] data = [bitmapClass TIFFRepresentationOfImageRepsInArray: [self _representationsWithCachedImages: NO]
usingCompression: comp usingCompression: comp
factor: aFloat]; factor: aFloat];

View file

@ -41,7 +41,8 @@
/* Structure to store common information about a tiff. */ /* Structure to store common information about a tiff. */
typedef struct { typedef struct {
uint32 imageNumber; uint16 numImages; /* number of images in tiff */
uint16 imageNumber; /* number of current image */
uint32 subfileType; uint32 subfileType;
uint32 width; uint32 width;
uint32 height; uint32 height;
@ -53,7 +54,6 @@ typedef struct {
uint16 extraSamples; /* Alpha */ uint16 extraSamples; /* Alpha */
int assocAlpha; int assocAlpha;
int quality; /* compression quality (for jpeg) 1 to 255 */ int quality; /* compression quality (for jpeg) 1 to 255 */
int numImages; /* number of images in tiff */
int error; int error;
float xdpi; float xdpi;
float ydpi; float ydpi;

View file

@ -152,9 +152,10 @@ TiffHandleSeek(thandle_t handle, toff_t offset, int mode)
case SEEK_SET: chand->position = offset; break; case SEEK_SET: chand->position = offset; break;
case SEEK_CUR: chand->position += offset; break; case SEEK_CUR: chand->position += offset; break;
case SEEK_END: case SEEK_END:
// FIXME: Not sure whether this check is correct
if (offset > 0 && chand->mode == 'r') if (offset > 0 && chand->mode == 'r')
return 0; return 0;
chand->position += offset; break; chand->position = chand->size - ((chand->size > 0) ? 1 : 0) + offset;
break; break;
} }
return chand->position; return chand->position;
@ -260,6 +261,7 @@ NSTiffGetImageCount(TIFF* image)
{ {
dircount++; dircount++;
} }
TIFFSetDirectory(image, 0);
return dircount; return dircount;
} }
@ -472,17 +474,25 @@ int
NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data) NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
{ {
void* buf = (void*)data; void* buf = (void*)data;
uint16 sample_info[2]; uint16 sample_info[1];
int i; int i;
unsigned int row; unsigned int row;
int error = 0; int error = 0;
tmsize_t scan_line_size; tmsize_t scan_line_size;
if (info->numImages > 1)
{
/* Set the page number */
TIFFSetField(image, TIFFTAG_PAGENUMBER, info->imageNumber, info->numImages);
}
TIFFSetField(image, TIFFTAG_IMAGEWIDTH, info->width); TIFFSetField(image, TIFFTAG_IMAGEWIDTH, info->width);
TIFFSetField(image, TIFFTAG_IMAGELENGTH, info->height); TIFFSetField(image, TIFFTAG_IMAGELENGTH, info->height);
TIFFSetField(image, TIFFTAG_COMPRESSION, info->compression); TIFFSetField(image, TIFFTAG_COMPRESSION, info->compression);
if (info->compression == COMPRESSION_JPEG) if (info->compression == COMPRESSION_JPEG)
TIFFSetField(image, TIFFTAG_JPEGQUALITY, info->quality); {
TIFFSetField(image, TIFFTAG_JPEGQUALITY, info->quality);
}
TIFFSetField(image, TIFFTAG_SUBFILETYPE, info->subfileType); TIFFSetField(image, TIFFTAG_SUBFILETYPE, info->subfileType);
TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, info->bitsPerSample); TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, info->bitsPerSample);
TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, info->samplesPerPixel); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, info->samplesPerPixel);
@ -549,7 +559,11 @@ NSTiffWrite(TIFF *image, NSTiffInfo *info, unsigned char *data)
return -1; return -1;
break; break;
} }
// Write out the directory as there may be more images comming
TIFFWriteDirectory(image);
TIFFFlush(image);
return error; return error;
} }