1996-05-30 20:03:15 +00:00
|
|
|
/*
|
|
|
|
NSBitmapImageRep.m
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
Bitmap image representation.
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
Copyright (C) 1996 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
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
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 Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
1996-08-22 18:51:08 +00:00
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
You should have received a copy of the GNU Library General Public
|
1996-10-18 17:14:13 +00:00
|
|
|
License along with this library; see the file COPYING.LIB.
|
|
|
|
If not, write to the Free Software Foundation,
|
|
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1996-08-22 18:51:08 +00:00
|
|
|
*/
|
|
|
|
|
1997-09-23 22:43:24 +00:00
|
|
|
#include <gnustep/gui/config.h>
|
1996-08-22 18:51:08 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <math.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <tiff.h>
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
#include <Foundation/NSException.h>
|
|
|
|
#include <Foundation/NSArray.h>
|
|
|
|
#include <Foundation/NSData.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <AppKit/NSGraphics.h>
|
|
|
|
#include <AppKit/NSPasteboard.h>
|
1996-08-22 18:51:08 +00:00
|
|
|
#include <AppKit/NSBitmapImageRep.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <AppKit/AppKitExceptions.h>
|
1997-08-27 21:20:19 +00:00
|
|
|
|
|
|
|
#include <gnustep/gui/config.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <gnustep/gui/nsimage-tiff.h>
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
/* Maximum number of planes */
|
|
|
|
#define MAX_PLANES 5
|
|
|
|
|
|
|
|
/* Backend protocol - methods that must be implemented by the backend to
|
|
|
|
complete the class */
|
|
|
|
@protocol NXBitmapImageRepBackend
|
|
|
|
- (BOOL) draw;
|
|
|
|
@end
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
@implementation NSBitmapImageRep
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* Given a TIFF image (from the libtiff library), load the image information
|
|
|
|
into our data structure. Reads the specified image. */
|
|
|
|
- _initFromImage: (TIFF *)image number: (int)imageNumber
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
NSString* space;
|
|
|
|
NSTiffInfo* info;
|
|
|
|
|
|
|
|
info = NSTiffGetInfo(imageNumber, image);
|
|
|
|
if (!info)
|
|
|
|
{
|
|
|
|
[NSException raise:NSTIFFException format: @"Read invalid TIFF info"];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 8-bit RGB will be converted to 24-bit by the tiff routines, so account
|
|
|
|
for this. */
|
|
|
|
space = nil;
|
|
|
|
switch(info->photoInterp)
|
|
|
|
{
|
|
|
|
case PHOTOMETRIC_MINISBLACK: space = NSDeviceWhiteColorSpace; break;
|
|
|
|
case PHOTOMETRIC_MINISWHITE: space = NSDeviceBlackColorSpace; break;
|
|
|
|
case PHOTOMETRIC_RGB: space = NSDeviceRGBColorSpace; break;
|
|
|
|
case PHOTOMETRIC_PALETTE:
|
|
|
|
space = NSDeviceRGBColorSpace;
|
|
|
|
info->samplesPerPixel = 3;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
[self initWithBitmapDataPlanes: NULL
|
|
|
|
pixelsWide: info->width
|
|
|
|
pixelsHigh: info->height
|
|
|
|
bitsPerSample: info->bitsPerSample
|
|
|
|
samplesPerPixel: info->samplesPerPixel
|
|
|
|
hasAlpha: (info->samplesPerPixel > 3)
|
|
|
|
isPlanar: (info->planarConfig == PLANARCONFIG_SEPARATE)
|
|
|
|
colorSpaceName: space
|
|
|
|
bytesPerRow: 0
|
|
|
|
bitsPerPixel: 0];
|
|
|
|
compression = info->compression;
|
1999-12-28 16:02:01 +00:00
|
|
|
comp_factor = 255 * (1 - ((float)info->quality)/100.0);
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
if (NSTiffRead(imageNumber, image, NULL, [self bitmapData]))
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[NSException raise:NSTIFFException format: @"Read invalid TIFF image"];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
1996-08-22 18:51:08 +00:00
|
|
|
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
+ (id) imageRepWithData: (NSData *)tiffData
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
NSArray* array;
|
|
|
|
|
|
|
|
array = [self imageRepsWithData: tiffData];
|
|
|
|
if ([array count])
|
|
|
|
return [array objectAtIndex: 0];
|
1996-05-30 20:03:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
+ (NSArray*) imageRepsWithData: (NSData *)tiffData
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
int images;
|
|
|
|
TIFF *image;
|
|
|
|
NSTiffInfo *info;
|
|
|
|
NSMutableArray*array;
|
1996-08-22 18:51:08 +00:00
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
image = NSTiffOpenDataRead((char *)[tiffData bytes], [tiffData length]);
|
1996-08-22 18:51:08 +00:00
|
|
|
if (!image)
|
|
|
|
{
|
|
|
|
[NSException raise:NSTIFFException format: @"Read invalid TIFF data"];
|
|
|
|
}
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity:1];
|
|
|
|
images = 0;
|
|
|
|
while ((info = NSTiffGetInfo(images, image)))
|
|
|
|
{
|
|
|
|
NSBitmapImageRep* imageRep;
|
|
|
|
|
|
|
|
OBJC_FREE(info);
|
1999-12-28 16:02:01 +00:00
|
|
|
imageRep = AUTORELEASE([[[self class] alloc]
|
|
|
|
_initFromImage: image number: images]);
|
1996-08-22 18:51:08 +00:00
|
|
|
[array addObject: imageRep];
|
|
|
|
images++;
|
|
|
|
}
|
|
|
|
NSTiffClose(image);
|
|
|
|
|
|
|
|
return array;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* Loads only the default (first) image from the TIFF image contained in
|
|
|
|
data. */
|
|
|
|
- (id) initWithData: (NSData *)tiffData
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
TIFF *image;
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
image = NSTiffOpenDataRead((char *)[tiffData bytes], [tiffData length]);
|
|
|
|
if (image == 0)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
[NSException raise:NSTIFFException format: @"Read invalid TIFF data"];
|
|
|
|
}
|
|
|
|
|
|
|
|
[self _initFromImage:image number: -1];
|
|
|
|
NSTiffClose(image);
|
|
|
|
return self;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (id) initWithFocusedViewRect: (NSRect)rect
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return [self notImplemented: _cmd];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
/* This is the designated initializer */
|
1996-09-08 14:32:34 +00:00
|
|
|
/* Note: If data is actaully passed to us in planes, we DO NOT own this
|
|
|
|
data and we DO NOT copy it. Just assume that it will always be available.
|
|
|
|
*/
|
1996-08-22 18:51:08 +00:00
|
|
|
- (id) initWithBitmapDataPlanes: (unsigned char **)planes
|
|
|
|
pixelsWide: (int)width
|
|
|
|
pixelsHigh: (int)height
|
|
|
|
bitsPerSample: (int)bps
|
|
|
|
samplesPerPixel: (int)spp
|
|
|
|
hasAlpha: (BOOL)alpha
|
1996-09-08 14:32:34 +00:00
|
|
|
isPlanar: (BOOL)isPlanar
|
1996-08-22 18:51:08 +00:00
|
|
|
colorSpaceName: (NSString *)colorSpaceName
|
|
|
|
bytesPerRow: (int)rowBytes
|
|
|
|
bitsPerPixel: (int)pixelBits;
|
|
|
|
{
|
|
|
|
if (!bps || !spp || !width || !height)
|
|
|
|
{
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
format: @"Required arguments not specified creating NSBitmapImageRep"];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
_pixelsWide = width;
|
|
|
|
_pixelsHigh = height;
|
|
|
|
size.width = width;
|
|
|
|
size.height = height;
|
|
|
|
bitsPerSample = bps;
|
|
|
|
numColors = spp;
|
|
|
|
hasAlpha = alpha;
|
1996-09-08 14:32:34 +00:00
|
|
|
_isPlanar = isPlanar;
|
1999-12-28 16:02:01 +00:00
|
|
|
_colorSpace = RETAIN(colorSpaceName);
|
1996-08-22 18:51:08 +00:00
|
|
|
if (!pixelBits)
|
1996-09-08 14:32:34 +00:00
|
|
|
pixelBits = bps * ((_isPlanar) ? 1 : spp);
|
1996-08-22 18:51:08 +00:00
|
|
|
bitsPerPixel = pixelBits;
|
|
|
|
if (!rowBytes)
|
|
|
|
rowBytes = ceil((float)width * bitsPerPixel / 8);
|
|
|
|
bytesPerRow = rowBytes;
|
|
|
|
|
|
|
|
if (planes)
|
|
|
|
{
|
1996-09-08 14:32:34 +00:00
|
|
|
int i;
|
|
|
|
OBJC_MALLOC(imagePlanes, unsigned char*, MAX_PLANES);
|
|
|
|
for (i = 0; i < MAX_PLANES; i++)
|
|
|
|
imagePlanes[i] = NULL;
|
|
|
|
for (i = 0; i < ((_isPlanar) ? numColors : 1); i++)
|
|
|
|
imagePlanes[i] = planes[i];
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
1999-12-28 20:26:07 +00:00
|
|
|
if (alpha)
|
|
|
|
{
|
|
|
|
unsigned char *bData = (unsigned char*)[self bitmapData];
|
|
|
|
BOOL allOpaque = YES;
|
|
|
|
unsigned offset = numColors - 1;
|
|
|
|
unsigned limit = size.height * size.width;
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
for (i = 0; i < limit; i++)
|
|
|
|
{
|
|
|
|
unsigned a;
|
|
|
|
|
|
|
|
bData += offset;
|
|
|
|
a = *bData++;
|
|
|
|
if (a != 255)
|
|
|
|
{
|
|
|
|
allOpaque = NO;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[self setOpaque: allOpaque];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[self setOpaque: YES];
|
|
|
|
}
|
1996-08-22 18:51:08 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
OBJC_FREE(imagePlanes);
|
1999-12-28 16:02:01 +00:00
|
|
|
RELEASE(imageData);
|
1996-08-22 18:51:08 +00:00
|
|
|
[super dealloc];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1999-04-06 14:09:13 +00:00
|
|
|
- (id) copyWithZone: (NSZone *)zone
|
|
|
|
{
|
|
|
|
NSBitmapImageRep *copy;
|
|
|
|
|
|
|
|
copy = (NSBitmapImageRep*)[super copyWithZone: zone];
|
|
|
|
|
|
|
|
copy->bytesPerRow = bytesPerRow;
|
|
|
|
copy->numColors = numColors;
|
|
|
|
copy->bitsPerPixel = bitsPerPixel;
|
|
|
|
copy->compression = compression;
|
1999-12-28 16:02:01 +00:00
|
|
|
copy->comp_factor = comp_factor;
|
1999-04-06 14:09:13 +00:00
|
|
|
copy->_isPlanar = _isPlanar;
|
|
|
|
copy->imagePlanes = 0;
|
|
|
|
copy->imageData = [imageData copy];
|
|
|
|
|
|
|
|
return copy;
|
|
|
|
}
|
1999-12-28 16:02:01 +00:00
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
+ (BOOL) canInitWithData: (NSData *)data
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
TIFF *image = NULL;
|
|
|
|
image = NSTiffOpenDataRead((char *)[data bytes], [data length]);
|
1996-08-22 18:51:08 +00:00
|
|
|
NSTiffClose(image);
|
|
|
|
|
|
|
|
return (image) ? YES : NO;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
+ (BOOL) canInitWithPasteboard: (NSPasteboard *)pasteboard
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
return [[pasteboard types] containsObject: NSTIFFPboardType];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
+ (NSArray *) imageFileTypes
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return [self imageUnfilteredFileTypes];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) imagePasteboardTypes
|
|
|
|
{
|
|
|
|
return [self imageUnfilteredPasteboardTypes];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) imageUnfilteredFileTypes
|
|
|
|
{
|
|
|
|
return [NSArray arrayWithObjects: @"tiff", @"tif", nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) imageUnfilteredPasteboardTypes
|
|
|
|
{
|
|
|
|
return [NSArray arrayWithObjects: NSTIFFPboardType, nil];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-05-30 20:03:15 +00:00
|
|
|
// Getting Information about the Image
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-08-22 18:51:08 +00:00
|
|
|
- (int) bitsPerPixel
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return bitsPerPixel;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (int) samplesPerPixel
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return numColors;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (BOOL) isPlanar
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-09-08 14:32:34 +00:00
|
|
|
return _isPlanar;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (int) numberOfPlanes
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-09-08 14:32:34 +00:00
|
|
|
return (_isPlanar) ? numColors : 1;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (int) bytesPerPlane
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return bytesPerRow*_pixelsHigh;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (int) bytesPerRow
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
return bytesPerRow;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-05-30 20:03:15 +00:00
|
|
|
// Getting Image Data
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-08-22 18:51:08 +00:00
|
|
|
- (unsigned char *) bitmapData
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
unsigned char *planes[MAX_PLANES];
|
|
|
|
[self getBitmapDataPlanes: planes];
|
1997-01-31 13:40:15 +00:00
|
|
|
return planes[0];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1996-08-22 18:51:08 +00:00
|
|
|
- (void) getBitmapDataPlanes: (unsigned char **)data
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
1997-01-31 13:40:15 +00:00
|
|
|
if (!imagePlanes || !imagePlanes[0])
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
long length;
|
|
|
|
unsigned char* bits;
|
|
|
|
|
1996-09-08 14:32:34 +00:00
|
|
|
length = (long)numColors * bytesPerRow * _pixelsHigh
|
|
|
|
* sizeof(unsigned char);
|
1999-12-28 16:02:01 +00:00
|
|
|
imageData = RETAIN([NSMutableData dataWithLength: length]);
|
1996-09-08 14:32:34 +00:00
|
|
|
if (!imagePlanes)
|
|
|
|
OBJC_MALLOC(imagePlanes, unsigned char*, MAX_PLANES);
|
1996-08-22 18:51:08 +00:00
|
|
|
bits = [imageData mutableBytes];
|
1996-09-08 14:32:34 +00:00
|
|
|
if (_isPlanar)
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
|
|
|
for (i=1; i < numColors; i++)
|
|
|
|
imagePlanes[i] = bits + i*bytesPerRow * _pixelsHigh;
|
|
|
|
for (i= numColors; i < MAX_PLANES; i++)
|
|
|
|
imagePlanes[i] = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1996-09-08 14:32:34 +00:00
|
|
|
imagePlanes[0] = bits;
|
1996-08-22 18:51:08 +00:00
|
|
|
for (i= 1; i < MAX_PLANES; i++)
|
|
|
|
imagePlanes[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if (data)
|
|
|
|
for (i=0; i < numColors; i++)
|
|
|
|
data[i] = imagePlanes[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) draw
|
|
|
|
{
|
2000-01-03 16:05:22 +00:00
|
|
|
NSRect irect = NSMakeRect(0, 0, size.width, size.height);
|
|
|
|
NSDrawBitmap(irect,
|
1999-12-28 19:20:45 +00:00
|
|
|
_pixelsWide,
|
|
|
|
_pixelsHigh,
|
|
|
|
bitsPerSample,
|
|
|
|
numColors,
|
|
|
|
bitsPerPixel,
|
|
|
|
bytesPerRow,
|
|
|
|
_isPlanar,
|
|
|
|
hasAlpha,
|
|
|
|
_colorSpace,
|
|
|
|
imagePlanes);
|
|
|
|
return YES;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-05-30 20:03:15 +00:00
|
|
|
// Producing a TIFF Representation of the Image
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1999-12-28 16:02:01 +00:00
|
|
|
+ (NSData*) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self notImplemented: _cmd];
|
1996-05-30 20:03:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
+ (NSData*) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray
|
|
|
|
usingCompression: (NSTIFFCompression)type
|
|
|
|
factor: (float)factor
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1996-08-22 18:51:08 +00:00
|
|
|
[self notImplemented: _cmd];
|
1996-05-30 20:03:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
- (NSData*) TIFFRepresentation
|
|
|
|
{
|
|
|
|
NSTiffInfo info;
|
|
|
|
TIFF *image;
|
|
|
|
char *bytes = 0;
|
|
|
|
long length = 0;
|
|
|
|
|
|
|
|
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 == NSDeviceRGBColorSpace)
|
|
|
|
info.photoInterp = PHOTOMETRIC_RGB;
|
|
|
|
else if (_colorSpace == NSDeviceWhiteColorSpace)
|
|
|
|
info.photoInterp = PHOTOMETRIC_MINISBLACK;
|
|
|
|
else if (_colorSpace == NSDeviceBlackColorSpace)
|
|
|
|
info.photoInterp = PHOTOMETRIC_MINISWHITE;
|
|
|
|
else
|
|
|
|
info.photoInterp = PHOTOMETRIC_RGB;
|
|
|
|
|
|
|
|
info.compression = compression;
|
|
|
|
info.quality = (1 - ((float)comp_factor)/255.0) * 100;
|
|
|
|
info.numImages = 1;
|
|
|
|
info.error = 0;
|
|
|
|
|
|
|
|
image = NSTiffOpenDataWrite(&bytes, &length);
|
|
|
|
if (image == 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSTIFFException format: @"Write TIFF open failed"];
|
|
|
|
}
|
|
|
|
if (NSTiffWrite(image, &info, [self bitmapData]) != 0)
|
|
|
|
{
|
|
|
|
[NSException raise: NSTIFFException format: @"Write TIFF data failed"];
|
|
|
|
}
|
|
|
|
NSTiffClose(image);
|
|
|
|
return [NSData dataWithBytesNoCopy: bytes length: length];
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
- (NSData*) TIFFRepresentationUsingCompression: (NSTIFFCompression)type
|
|
|
|
factor: (float)factor
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
NSData *data;
|
|
|
|
NSTIFFCompression oldType = compression;
|
|
|
|
float oldFact = comp_factor;
|
|
|
|
|
|
|
|
[self setCompression: type factor: factor];
|
|
|
|
data = [self TIFFRepresentation];
|
|
|
|
[self setCompression: oldType factor: oldFact];
|
|
|
|
return data;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-05-30 20:03:15 +00:00
|
|
|
// Setting and Checking Compression Types
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-08-22 18:51:08 +00:00
|
|
|
+ (void) getTIFFCompressionTypes: (const NSTIFFCompression **)list
|
1999-12-28 16:02:01 +00:00
|
|
|
count: (int *)numTypes
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
static NSTIFFCompression types[] = {
|
|
|
|
NSTIFFCompressionNone,
|
|
|
|
NSTIFFCompressionCCITTFAX3,
|
|
|
|
NSTIFFCompressionCCITTFAX4,
|
|
|
|
NSTIFFCompressionLZW,
|
|
|
|
NSTIFFCompressionJPEG,
|
|
|
|
NSTIFFCompressionPackBits
|
|
|
|
};
|
|
|
|
|
|
|
|
*list = types;
|
|
|
|
*numTypes = sizeof(types)/sizeof(*types);
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
+ (NSString*) localizedNameForTIFFCompressionType: (NSTIFFCompression)type
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case NSTIFFCompressionNone: return @"NSTIFFCompressionNone";
|
|
|
|
case NSTIFFCompressionCCITTFAX3: return @"NSTIFFCompressionCCITTFAX3";
|
|
|
|
case NSTIFFCompressionCCITTFAX4: return @"NSTIFFCompressionCCITTFAX4";
|
|
|
|
case NSTIFFCompressionLZW: return @"NSTIFFCompressionLZW";
|
|
|
|
case NSTIFFCompressionJPEG: return @"NSTIFFCompressionJPEG";
|
|
|
|
case NSTIFFCompressionNEXT: return @"NSTIFFCompressionNEXT";
|
|
|
|
case NSTIFFCompressionPackBits: return @"NSTIFFCompressionPackBits";
|
|
|
|
case NSTIFFCompressionOldJPEG: return @"NSTIFFCompressionOldJPEG";
|
|
|
|
default: return nil;
|
|
|
|
}
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
- (BOOL) canBeCompressedUsing: (NSTIFFCompression)type
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case NSTIFFCompressionCCITTFAX3:
|
|
|
|
case NSTIFFCompressionCCITTFAX4:
|
|
|
|
if (numColors == 1 && bitsPerSample == 1)
|
|
|
|
return YES;
|
|
|
|
else
|
|
|
|
return NO;
|
|
|
|
|
|
|
|
case NSTIFFCompressionNone:
|
|
|
|
case NSTIFFCompressionLZW:
|
|
|
|
case NSTIFFCompressionJPEG:
|
|
|
|
case NSTIFFCompressionPackBits:
|
|
|
|
return YES;
|
|
|
|
|
|
|
|
case NSTIFFCompressionNEXT:
|
|
|
|
case NSTIFFCompressionOldJPEG:
|
|
|
|
default:
|
|
|
|
return NO;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
- (void) getCompression: (NSTIFFCompression*)type
|
|
|
|
factor: (float*)factor
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
*type = compression;
|
|
|
|
*factor = comp_factor;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
|
|
|
|
1999-12-28 16:02:01 +00:00
|
|
|
- (void) setCompression: (NSTIFFCompression)type
|
|
|
|
factor: (float)factor
|
1996-08-22 18:51:08 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
compression = type;
|
|
|
|
comp_factor = factor;
|
1996-08-22 18:51:08 +00:00
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1996-05-30 20:03:15 +00:00
|
|
|
// NSCoding protocol
|
1997-01-31 20:14:40 +00:00
|
|
|
//
|
1999-03-02 08:58:30 +00:00
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
NSData *data = [self TIFFRepresentation];
|
|
|
|
|
|
|
|
[super encodeWithCoder: aCoder];
|
|
|
|
[data encodeWithCoder: aCoder];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:58:30 +00:00
|
|
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-12-28 16:02:01 +00:00
|
|
|
NSData *data;
|
|
|
|
|
|
|
|
self = [super initWithCoder: aDecoder];
|
|
|
|
data = [aDecoder decodeObject];
|
|
|
|
return [self initWithData: data];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|