mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-25 16:20:58 +00:00
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4033 72102866-910b-0410-8b05-ffd578937521
436 lines
9.6 KiB
Objective-C
436 lines
9.6 KiB
Objective-C
/*
|
|
NSBitmapImageRep.m
|
|
|
|
Bitmap image representation.
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
Author: Adam Fedor <fedor@colorado.edu>
|
|
Date: Feb 1996
|
|
|
|
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.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
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.
|
|
*/
|
|
|
|
#include <gnustep/gui/config.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <tiff.h>
|
|
|
|
#include <Foundation/NSException.h>
|
|
#include <Foundation/NSArray.h>
|
|
#include <Foundation/NSData.h>
|
|
#include <AppKit/NSGraphics.h>
|
|
#include <AppKit/NSPasteboard.h>
|
|
#include <AppKit/NSBitmapImageRep.h>
|
|
#include <AppKit/AppKitExceptions.h>
|
|
|
|
#include <gnustep/gui/config.h>
|
|
#include <gnustep/gui/nsimage-tiff.h>
|
|
|
|
/* 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
|
|
|
|
@implementation NSBitmapImageRep
|
|
|
|
/* 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
|
|
{
|
|
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;
|
|
|
|
if (NSTiffRead(imageNumber, image, NULL, [self bitmapData]))
|
|
{
|
|
[NSException raise:NSTIFFException format: @"Read invalid TIFF image"];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
+ (id) imageRepWithData: (NSData *)tiffData
|
|
{
|
|
NSArray* array;
|
|
|
|
array = [self imageRepsWithData: tiffData];
|
|
if ([array count])
|
|
return [array objectAtIndex: 0];
|
|
return nil;
|
|
}
|
|
|
|
+ (NSArray *) imageRepsWithData: (NSData *)tiffData
|
|
{
|
|
int images;
|
|
TIFF* image;
|
|
NSTiffInfo* info;
|
|
NSMutableArray* array;
|
|
|
|
image = NSTiffOpenData((char *)[tiffData bytes], [tiffData length],
|
|
"r", NULL);
|
|
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);
|
|
imageRep = [[[[self class] alloc]
|
|
_initFromImage: image number: images] autorelease];
|
|
[array addObject: imageRep];
|
|
images++;
|
|
}
|
|
NSTiffClose(image);
|
|
|
|
return array;
|
|
}
|
|
|
|
/* Loads only the default (first) image from the TIFF image contained in
|
|
data. */
|
|
- (id) initWithData: (NSData *)tiffData
|
|
{
|
|
TIFF *image;
|
|
|
|
image = NSTiffOpenData((char *)[tiffData bytes], [tiffData length],
|
|
"r", NULL);
|
|
if (!image)
|
|
{
|
|
[NSException raise:NSTIFFException format: @"Read invalid TIFF data"];
|
|
}
|
|
|
|
[self _initFromImage:image number: -1];
|
|
NSTiffClose(image);
|
|
return self;
|
|
}
|
|
|
|
- (id) initWithFocusedViewRect: (NSRect)rect
|
|
{
|
|
return [self notImplemented: _cmd];
|
|
}
|
|
|
|
/* This is the designated initializer */
|
|
/* 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.
|
|
*/
|
|
- (id) initWithBitmapDataPlanes: (unsigned char **)planes
|
|
pixelsWide: (int)width
|
|
pixelsHigh: (int)height
|
|
bitsPerSample: (int)bps
|
|
samplesPerPixel: (int)spp
|
|
hasAlpha: (BOOL)alpha
|
|
isPlanar: (BOOL)isPlanar
|
|
colorSpaceName: (NSString *)colorSpaceName
|
|
bytesPerRow: (int)rowBytes
|
|
bitsPerPixel: (int)pixelBits;
|
|
{
|
|
if (!bps || !spp || !width || !height)
|
|
{
|
|
[NSException raise: NSInvalidArgumentException
|
|
format: @"Required arguments not specified creating NSBitmapImageRep"];
|
|
}
|
|
|
|
_pixelsWide = width;
|
|
_pixelsHigh = height;
|
|
size.width = width;
|
|
size.height = height;
|
|
bitsPerSample = bps;
|
|
numColors = spp;
|
|
hasAlpha = alpha;
|
|
_isPlanar = isPlanar;
|
|
_colorSpace = [colorSpaceName retain];
|
|
if (!pixelBits)
|
|
pixelBits = bps * ((_isPlanar) ? 1 : spp);
|
|
bitsPerPixel = pixelBits;
|
|
if (!rowBytes)
|
|
rowBytes = ceil((float)width * bitsPerPixel / 8);
|
|
bytesPerRow = rowBytes;
|
|
|
|
if (planes)
|
|
{
|
|
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];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
OBJC_FREE(imagePlanes);
|
|
[imageData release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (id) copyWithZone: (NSZone *)zone
|
|
{
|
|
NSBitmapImageRep *copy;
|
|
|
|
copy = (NSBitmapImageRep*)[super copyWithZone: zone];
|
|
|
|
copy->bytesPerRow = bytesPerRow;
|
|
copy->numColors = numColors;
|
|
copy->bitsPerPixel = bitsPerPixel;
|
|
copy->compression = compression;
|
|
copy->_isPlanar = _isPlanar;
|
|
copy->imagePlanes = 0;
|
|
copy->imageData = [imageData copy];
|
|
|
|
return copy;
|
|
}
|
|
+ (BOOL) canInitWithData: (NSData *)data
|
|
{
|
|
TIFF *image = NULL;
|
|
image = NSTiffOpenData((char *)[data bytes], [data length], "r", NULL);
|
|
NSTiffClose(image);
|
|
|
|
return (image) ? YES : NO;
|
|
}
|
|
|
|
+ (BOOL) canInitWithPasteboard: (NSPasteboard *)pasteboard
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return NO;
|
|
}
|
|
|
|
+ (NSArray *) imageFileTypes
|
|
{
|
|
return [self imageUnfilteredFileTypes];
|
|
}
|
|
|
|
+ (NSArray *) imagePasteboardTypes
|
|
{
|
|
return [self imageUnfilteredPasteboardTypes];
|
|
}
|
|
|
|
+ (NSArray *) imageUnfilteredFileTypes
|
|
{
|
|
return [NSArray arrayWithObjects: @"tiff", @"tif", nil];
|
|
}
|
|
|
|
+ (NSArray *) imageUnfilteredPasteboardTypes
|
|
{
|
|
return [NSArray arrayWithObjects: NSTIFFPboardType, nil];
|
|
}
|
|
|
|
//
|
|
// Getting Information about the Image
|
|
//
|
|
- (int) bitsPerPixel
|
|
{
|
|
return bitsPerPixel;
|
|
}
|
|
|
|
- (int) samplesPerPixel
|
|
{
|
|
return numColors;
|
|
}
|
|
|
|
- (BOOL) isPlanar
|
|
{
|
|
return _isPlanar;
|
|
}
|
|
|
|
- (int) numberOfPlanes
|
|
{
|
|
return (_isPlanar) ? numColors : 1;
|
|
}
|
|
|
|
- (int) bytesPerPlane
|
|
{
|
|
return bytesPerRow*_pixelsHigh;
|
|
}
|
|
|
|
- (int) bytesPerRow
|
|
{
|
|
return bytesPerRow;
|
|
}
|
|
|
|
//
|
|
// Getting Image Data
|
|
//
|
|
- (unsigned char *) bitmapData
|
|
{
|
|
unsigned char *planes[MAX_PLANES];
|
|
[self getBitmapDataPlanes: planes];
|
|
return planes[0];
|
|
}
|
|
|
|
- (void) getBitmapDataPlanes: (unsigned char **)data
|
|
{
|
|
int i;
|
|
|
|
if (!imagePlanes || !imagePlanes[0])
|
|
{
|
|
long length;
|
|
unsigned char* bits;
|
|
|
|
length = (long)numColors * bytesPerRow * _pixelsHigh
|
|
* sizeof(unsigned char);
|
|
imageData = [[NSMutableData dataWithLength: length] retain];
|
|
if (!imagePlanes)
|
|
OBJC_MALLOC(imagePlanes, unsigned char*, MAX_PLANES);
|
|
bits = [imageData mutableBytes];
|
|
if (_isPlanar)
|
|
{
|
|
for (i=1; i < numColors; i++)
|
|
imagePlanes[i] = bits + i*bytesPerRow * _pixelsHigh;
|
|
for (i= numColors; i < MAX_PLANES; i++)
|
|
imagePlanes[i] = NULL;
|
|
}
|
|
else
|
|
{
|
|
imagePlanes[0] = bits;
|
|
for (i= 1; i < MAX_PLANES; i++)
|
|
imagePlanes[i] = NULL;
|
|
}
|
|
|
|
}
|
|
if (data)
|
|
for (i=0; i < numColors; i++)
|
|
data[i] = imagePlanes[i];
|
|
}
|
|
|
|
- (BOOL) draw
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
//
|
|
// Producing a TIFF Representation of the Image
|
|
//
|
|
+ (NSData *) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
+ (NSData *) TIFFRepresentationOfImageRepsInArray: (NSArray *)anArray
|
|
usingCompression: (NSTIFFCompression)compressionType
|
|
factor: (float)factor
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
- (NSData *) TIFFRepresentation
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
- (NSData *) TIFFRepresentationUsingCompression: (NSTIFFCompression)compressionType
|
|
factor: (float)factor
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
//
|
|
// Setting and Checking Compression Types
|
|
//
|
|
+ (void) getTIFFCompressionTypes: (const NSTIFFCompression **)list
|
|
count: (int *)numTypes
|
|
{
|
|
[self notImplemented: _cmd];
|
|
}
|
|
|
|
+ (NSString *) localizedNameForTIFFCompressionType: (NSTIFFCompression)compression
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
- (BOOL) canBeCompressedUsing: (NSTIFFCompression)compression
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return NO;
|
|
}
|
|
|
|
- (void) getCompression: (NSTIFFCompression *)compression
|
|
factor: (float *)factor
|
|
{
|
|
[self notImplemented: _cmd];
|
|
}
|
|
|
|
- (void) setCompression: (NSTIFFCompression)compression
|
|
factor: (float)factor
|
|
{
|
|
[self notImplemented: _cmd];
|
|
}
|
|
|
|
//
|
|
// NSCoding protocol
|
|
//
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
|
{
|
|
[self notImplemented: _cmd];
|
|
}
|
|
|
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
@end
|