diff --git a/ChangeLog b/ChangeLog index d975f481f..64a219b17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2000-04-13 Adam Fedor + + * Source/NSApplication.m ([NSAppIconView -setImage:]): Remove + extra lock/unlock focus. + ([NSApplication -finishLaunching]): More specific error information. + + * Source/NSWindow.m (-setFrameOrigin:): Don't re-display. + (-setFrameTopLeftPoint): Likewise. + (_initDefaults): Set needs_display flag. + + * Source/NSBitmapImageRep.m (-_initFromImage:number:): Use new + Tiff routines, log message and return nil rather than raise exception. + * Source/tiff.m (NSTiffGetInfo): Tidy, get alpha info correctly. + (NSTiffRead): Bug fixes, particularly reading planar images. + (NSTiffError): New function. + (NSTiffWarning): Likewise. + (NSTiffGetImageCount): Likewise. + 2000-04-13 Richard Frith-Macdonald * Source/NSMenu.m: ([-_setOwnedBypopUp:]) set correct window level for diff --git a/Headers/gnustep/gui/nsimage-tiff.h b/Headers/gnustep/gui/nsimage-tiff.h index c7ab009b5..924a90af9 100644 --- a/Headers/gnustep/gui/nsimage-tiff.h +++ b/Headers/gnustep/gui/nsimage-tiff.h @@ -67,9 +67,9 @@ extern TIFF* NSTiffOpenDataRead(const char* data, long size); extern TIFF* NSTiffOpenDataWrite(char **data, long *size); extern int NSTiffClose(TIFF* image); +extern int NSTiffGetImageCount(TIFF* image); extern int NSTiffWrite(TIFF* image, NSTiffInfo* info, char* data); -extern int NSTiffRead(int imageNumber, TIFF* image, NSTiffInfo* info, - char* data); +extern int NSTiffRead(TIFF* image, NSTiffInfo* info, char* data); extern NSTiffInfo* NSTiffGetInfo(int imageNumber, TIFF* image); extern NSTiffColormap* NSTiffGetColormap(TIFF* image); diff --git a/Source/NSApplication.m b/Source/NSApplication.m index e33037d02..253233240 100644 --- a/Source/NSApplication.m +++ b/Source/NSApplication.m @@ -215,12 +215,10 @@ static NSCell* tileCell = nil; - (void) setImage: (NSImage *)anImage { - [self lockFocus]; [tileCell drawWithFrame: NSMakeRect(0,0,64,64) inView: self]; [dragCell setImage: anImage]; [dragCell drawWithFrame: NSMakeRect(8,8,48,48) inView: self]; [_window flushWindow]; - [self unlockFocus]; } @end @@ -688,10 +686,16 @@ static NSCell* tileCell = nil; userInfo = [NSDictionary dictionaryWithObject: [[NSProcessInfo processInfo] processName] forKey: @"NSApplicationName"]; - [[[NSWorkspace sharedWorkspace] notificationCenter] - postNotificationName: NSWorkspaceDidLaunchApplicationNotification - object: self - userInfo: userInfo]; + NS_DURING + [[[NSWorkspace sharedWorkspace] notificationCenter] + postNotificationName: NSWorkspaceDidLaunchApplicationNotification + object: self + userInfo: userInfo]; + NS_HANDLER + NSLog(@"Problem during launch app notification: %@", + [localException reason]); + [localException raise]; + NS_ENDHANDLER } - (void) dealloc diff --git a/Source/NSBitmapImageRep.m b/Source/NSBitmapImageRep.m index 3cd65c468..c5b33819c 100644 --- a/Source/NSBitmapImageRep.m +++ b/Source/NSBitmapImageRep.m @@ -60,10 +60,12 @@ NSString* space; NSTiffInfo* info; + /* Seek to the correct image and get the dictionary information */ info = NSTiffGetInfo(imageNumber, image); if (!info) { - [NSException raise:NSTIFFException format: @"Read invalid TIFF info"]; + NSLog(@"Tiff read invalid TIFF info in directory %d", imageNumber); + return nil; } /* 8-bit RGB will be converted to 24-bit by the tiff routines, so account @@ -87,7 +89,7 @@ pixelsHigh: info->height bitsPerSample: info->bitsPerSample samplesPerPixel: info->samplesPerPixel - hasAlpha: (info->samplesPerPixel > 3) + hasAlpha: (info->extraSamples > 0) isPlanar: (info->planarConfig == PLANARCONFIG_SEPARATE) colorSpaceName: space bytesPerRow: 0 @@ -95,9 +97,10 @@ compression = info->compression; comp_factor = 255 * (1 - ((float)info->quality)/100.0); - if (NSTiffRead(imageNumber, image, NULL, [self bitmapData])) + if (NSTiffRead(image, info, [self bitmapData])) { - [NSException raise:NSTIFFException format: @"Read invalid TIFF image"]; + NSLog(@"Tiff read invalid TIFF image data in directory %d", imageNumber); + return nil; } return self; @@ -115,28 +118,26 @@ + (NSArray*) imageRepsWithData: (NSData *)tiffData { - int images; - TIFF *image; - NSTiffInfo *info; - NSMutableArray*array; + int i, images; + TIFF *image; + NSMutableArray *array; image = NSTiffOpenDataRead((char *)[tiffData bytes], [tiffData length]); - if (!image) + if (image == NULL) { - [NSException raise:NSTIFFException format: @"Read invalid TIFF data"]; + NSLog(@"Tiff unable to open/parse TIFF data"); + return nil; } - array = [NSMutableArray arrayWithCapacity:1]; - images = 0; - while ((info = NSTiffGetInfo(images, image))) + images = NSTiffGetImageCount(image); + NSDebugLLog(@"NSImage", @"Image contains %d directories", images); + array = [NSMutableArray arrayWithCapacity: images]; + for (i = 0; i < images; i++) { NSBitmapImageRep* imageRep; - - OBJC_FREE(info); - imageRep = AUTORELEASE([[[self class] alloc] - _initFromImage: image number: images]); - [array addObject: imageRep]; - images++; + imageRep = [[[self class] alloc] _initFromImage: image number: i]; + if (imageRep) + [array addObject: AUTORELEASE(imageRep)]; } NSTiffClose(image); @@ -357,6 +358,7 @@ if (!imagePlanes) OBJC_MALLOC(imagePlanes, unsigned char*, MAX_PLANES); bits = [imageData mutableBytes]; + imagePlanes[0] = bits; if (_isPlanar) { for (i=1; i < numColors; i++) @@ -366,7 +368,6 @@ } else { - imagePlanes[0] = bits; for (i= 1; i < MAX_PLANES; i++) imagePlanes[i] = NULL; } diff --git a/Source/NSView.m b/Source/NSView.m index 500246040..0c62299db 100644 --- a/Source/NSView.m +++ b/Source/NSView.m @@ -1328,6 +1328,8 @@ GSSetDragTypes(NSView* obj, NSArray *types) [ctxt lockFocusView: self inRect: rect]; wrect = [self convertRect: rect toView: nil]; + NSDebugLLog(@"NSView", @"Displaying rect \n\t%@\n\t window %p", + NSStringFromRect(wrect), _window); window_t = (struct NSWindow_struct *)_window; [window_t->rectsBeingDrawn addObject: [NSValue valueWithRect: wrect]]; diff --git a/Source/NSWindow.m b/Source/NSWindow.m index ccee2b927..71be554c6 100644 --- a/Source/NSWindow.m +++ b/Source/NSWindow.m @@ -1263,7 +1263,7 @@ static NSMapTable* windowmaps = NULL; NSRect r = frame; r.origin = aPoint; - [self setFrame: r display: YES]; + [self setFrame: r display: NO]; } - (void) setFrameTopLeftPoint: (NSPoint)aPoint @@ -1272,7 +1272,7 @@ static NSMapTable* windowmaps = NULL; r.origin = aPoint; r.origin.y -= frame.size.height; - [self setFrame: r display: YES]; + [self setFrame: r display: NO]; } - (void) setMinSize: (NSSize)aSize @@ -3312,6 +3312,8 @@ resetCursorRectsForView(NSView *theView) _f.accepts_mouse_moved = NO; _f.has_opened = NO; _f.has_closed = NO; + + _rFlags.needs_display = YES; } @end diff --git a/Source/tiff.m b/Source/tiff.m index ea15ac0aa..1bea16aaf 100644 --- a/Source/tiff.m +++ b/Source/tiff.m @@ -79,12 +79,37 @@ typedef struct { long *outposition; } chandle_t; +static int tiff_error_handler_set = 0; + +static void +NSTiffError(const char *func, const char *msg, ...) +{ + NSString *format; + va_list ap; + + format = [NSString stringWithFormat: @"Tiff Error (%s) %s", func, msg]; + va_start (ap, msg); + NSLogv (format, ap); + va_end (ap); +} + +static void +NSTiffWarning(const char *func, const char *msg, ...) +{ + NSString *format; + va_list ap; + + format = [NSString stringWithFormat: @"Tiff Warning (%s) %s", func, msg]; + va_start (ap, msg); + NSLogv (format, ap); + va_end (ap); +} + /* Client functions that provide reading/writing of data for libtiff */ static tsize_t TiffHandleRead(thandle_t handle, tdata_t buf, toff_t count) { chandle_t* chand = (chandle_t *)handle; - NSDebugLLog(@"NSImage", @"TiffHandleRead\n"); if (chand->position >= chand->size) return 0; if (chand->position + count > chand->size) @@ -97,7 +122,6 @@ static tsize_t TiffHandleWrite(thandle_t handle, tdata_t buf, toff_t count) { chandle_t* chand = (chandle_t *)handle; - NSDebugLLog(@"NSImage", @"TiffHandleWrite\n"); if (chand->mode == "r") return 0; if (chand->position + count > chand->size) @@ -120,7 +144,6 @@ static toff_t TiffHandleSeek(thandle_t handle, toff_t offset, int mode) { chandle_t* chand = (chandle_t *)handle; - NSDebugLLog(@"NSImage", @"TiffHandleSeek\n"); switch(mode) { case SEEK_SET: chand->position = offset; break; @@ -139,7 +162,6 @@ TiffHandleClose(thandle_t handle) { chandle_t* chand = (chandle_t *)handle; - NSDebugLLog(@"NSImage", @"TiffHandleClose\n"); /* Presumably, we don't need the handle anymore */ OBJC_FREE(chand); return 0; @@ -149,7 +171,6 @@ static toff_t TiffHandleSize(thandle_t handle) { chandle_t* chand = (chandle_t *)handle; - NSDebugLLog(@"NSImage", @"TiffHandleSize\n"); return chand->size; } @@ -158,7 +179,6 @@ TiffHandleMap(thandle_t handle, tdata_t* data, toff_t* size) { chandle_t* chand = (chandle_t *)handle; - NSDebugLLog(@"NSImage", @"TiffHandleMap\n"); *data = chand->data; *size = chand->size; @@ -168,7 +188,6 @@ TiffHandleMap(thandle_t handle, tdata_t* data, toff_t* size) static void TiffHandleUnmap(thandle_t handle, tdata_t data, toff_t size) { - NSDebugLLog(@"NSImage", @"TiffHandleUnmap\n"); /* Nothing to unmap. */ } @@ -177,7 +196,14 @@ TIFF* NSTiffOpenDataRead(const char* data, long size) { chandle_t* handle; - NSDebugLLog(@"NSImage", @"NSTiffOpenData\n"); + + if (tiff_error_handler_set == 0) + { + tiff_error_handler_set = 1; + TIFFSetErrorHandler(NSTiffError); + TIFFSetWarningHandler(NSTiffWarning); + } + OBJC_MALLOC(handle, chandle_t, 1); handle->data = (char*)data; handle->outdata = 0; @@ -185,7 +211,7 @@ NSTiffOpenDataRead(const char* data, long size) handle->outposition = 0; handle->size = size; handle->mode = "r"; - return TIFFClientOpen("NSData", "r", + return TIFFClientOpen("TiffData", "r", (thandle_t)handle, TiffHandleRead, TiffHandleWrite, TiffHandleSeek, TiffHandleClose, @@ -197,7 +223,6 @@ TIFF* NSTiffOpenDataWrite(char **data, long *size) { chandle_t* handle; - NSDebugLLog(@"NSImage", @"NSTiffOpenData\n"); OBJC_MALLOC(handle, chandle_t, 1); handle->data = *data; handle->outdata = data; @@ -205,7 +230,7 @@ NSTiffOpenDataWrite(char **data, long *size) handle->outposition = size; handle->size = *size; handle->mode = "w"; - return TIFFClientOpen("NSData", "w", + return TIFFClientOpen("TiffData", "w", (thandle_t)handle, TiffHandleRead, TiffHandleWrite, TiffHandleSeek, TiffHandleClose, @@ -220,6 +245,21 @@ NSTiffClose(TIFF* image) return 0; } +int +NSTiffGetImageCount(TIFF* image) +{ + int dircount = 1; + + if (image == NULL) + return 0; + + while (TIFFReadDirectory(image)) + { + dircount++; + } + return dircount; +} + /* Read some information about the image. Note that currently we don't determine numImages. */ NSTiffInfo * @@ -227,21 +267,23 @@ NSTiffGetInfo(int imageNumber, TIFF* image) { NSTiffInfo* info; - if (imageNumber >= 0 && !TIFFSetDirectory(image, imageNumber)) - { - return NULL; - } + if (image == NULL) + return NULL; OBJC_MALLOC(info, NSTiffInfo, 1); memset(info, 0, sizeof(NSTiffInfo)); if (imageNumber >= 0) - info->imageNumber = imageNumber; + { + TIFFSetDirectory(image, imageNumber); + info->imageNumber = imageNumber; + } TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &info->width); TIFFGetField(image, TIFFTAG_IMAGELENGTH, &info->height); TIFFGetField(image, TIFFTAG_COMPRESSION, &info->compression); TIFFGetField(image, TIFFTAG_JPEGQUALITY, &info->quality); TIFFGetField(image, TIFFTAG_SUBFILETYPE, &info->subfileType); + TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &info->extraSamples); /* If the following tags aren't present then use the TIFF defaults. */ TIFFGetFieldDefaulted(image, TIFFTAG_BITSPERSAMPLE, &info->bitsPerSample); @@ -275,13 +317,13 @@ NSTiffGetInfo(int imageNumber, TIFF* image) return info; } -#define READ_SCANLINE(sample) \ - if (TIFFReadScanline(image, buf, row, sample) < 0) { \ - NSLog(@"tiff: bad data read on line %d\n", row); \ - error = 1; \ - break; \ - } \ - inP = buf; +#define READ_SCANLINE(sample) \ + if (TIFFReadScanline(image, buf, row, sample) != 1) \ + { \ + NSLog(@"Tiff bad data read on line %d", row); \ + error = 1; \ + break; \ + } /* Read an image into a data array. The data array is assumed to have been already allocated to the correct size. @@ -290,84 +332,73 @@ NSTiffGetInfo(int imageNumber, TIFF* image) direct color images. Thus the data array should be large enough to hold this information. */ int -NSTiffRead(int imageNumber, TIFF* image, NSTiffInfo* info, char* data) +NSTiffRead(TIFF* image, NSTiffInfo* info, char* data) { int i; int row, col; int maxval; - int size; - int line; int error = 0; - u_char* inP; u_char* outP; u_char* buf; u_char* raster; - NSTiffInfo* newinfo; NSTiffColormap* map; int scan_line_size; if (data == NULL) return -1; - /* Make sure we're at the right image */ - if ((newinfo = NSTiffGetInfo(imageNumber, image)) == NULL) - return -1; - - if (info) - memcpy(info, newinfo, sizeof(NSTiffInfo)); - map = NULL; - if (newinfo->photoInterp == PHOTOMETRIC_PALETTE) + if (info->photoInterp == PHOTOMETRIC_PALETTE) { map = NSTiffGetColormap(image); if (!map) return -1; } - maxval = (1 << newinfo->bitsPerSample) - 1; - line = ceil((float)newinfo->width * newinfo->bitsPerSample / 8.0); - size = ceil((float)line * newinfo->height * newinfo->samplesPerPixel); + maxval = (1 << info->bitsPerSample) - 1; scan_line_size = TIFFScanlineSize(image); - OBJC_MALLOC(buf, u_char, TIFFScanlineSize(image)); + buf = _TIFFmalloc(scan_line_size); raster = (u_char *)data; outP = raster; - switch (newinfo->photoInterp) + switch (info->photoInterp) { case PHOTOMETRIC_MINISBLACK: case PHOTOMETRIC_MINISWHITE: - if (newinfo->planarConfig == PLANARCONFIG_CONTIG) + if (info->planarConfig == PLANARCONFIG_CONTIG) { - for (row = 0; row < newinfo->height; ++row) + for (row = 0; row < info->height; ++row) { - READ_SCANLINE(0) - for (col = 0; col < line*newinfo->samplesPerPixel; col++) - *outP++ = *inP++; + READ_SCANLINE(0); + memcpy(outP, buf, scan_line_size); + outP += scan_line_size; } } else { - for (i = 0; i < newinfo->samplesPerPixel; i++) - for (row = 0; row < newinfo->height; ++row) + for (i = 0; i < info->samplesPerPixel; i++) + for (row = 0; row < info->height; ++row) { - READ_SCANLINE(i) - for (col = 0; col < line; col++) - *outP++ = *inP++; + READ_SCANLINE(i); + memcpy(outP, buf, scan_line_size); + outP += scan_line_size; } } break; case PHOTOMETRIC_PALETTE: { - for (row = 0; row < newinfo->height; ++row) + for (row = 0; row < info->height; ++row) { - READ_SCANLINE(0) - for (col = 0; col < newinfo->width; col++) - { - *outP++ = map->red[*inP] / 256; - *outP++ = map->green[*inP] / 256; - *outP++ = map->blue[*inP] / 256; - inP++; - } + u_char *inP; + READ_SCANLINE(0); + inP = buf; + for (col = 0; col < info->width; col++) + { + *outP++ = map->red[*inP] / 256; + *outP++ = map->green[*inP] / 256; + *outP++ = map->blue[*inP] / 256; + inP++; + } } free(map->red); free(map->green); @@ -376,46 +407,39 @@ NSTiffRead(int imageNumber, TIFF* image, NSTiffInfo* info, char* data) } break; case PHOTOMETRIC_RGB: - if (newinfo->planarConfig == PLANARCONFIG_CONTIG) + if (info->planarConfig == PLANARCONFIG_CONTIG) { - NSDebugLLog(@"NSImage", @"PHOTOMETRIC_RGB: CONTIG\n"); - for (row = 0; row < newinfo->height; ++row) + for (row = 0; row < info->height; ++row) { - READ_SCANLINE(0) - for (col = 0; col < newinfo->width; col++) - for (i = 0; i < newinfo->samplesPerPixel; i++) - { - *outP++ = *inP++; - } + READ_SCANLINE(0); + memcpy(outP, buf, scan_line_size); + outP += scan_line_size; } } else { - NSDebugLLog(@"NSImage", @"PHOTOMETRIC_RGB: NOT CONTIG\n"); - for (i = 0; i < newinfo->samplesPerPixel; i++) - for (row = 0; row < newinfo->height; ++row) + for (i = 0; i < info->samplesPerPixel; i++) + for (row = 0; row < info->height; ++row) { - READ_SCANLINE(i) - for (col = 0; col < newinfo->width; col++) - { - *outP++ = *inP++; - } + READ_SCANLINE(i); + memcpy(outP, buf, scan_line_size); + outP += scan_line_size; } } break; default: - TIFFError(TIFFFileName(image), - "Can't read photometric %d", newinfo->photoInterp); + NSLog(@"Tiff can't read photometric %d", info->photoInterp); + error = 1; break; } - OBJC_FREE(newinfo); + _TIFFfree(buf); return error; } #define WRITE_SCANLINE(sample) \ if (TIFFWriteScanline(image, buf, row, sample) != 1) { \ - NSLog(@"tiff: bad data write on line %d\n", row); \ + NSLog(@"Tiff bad data write on line %d\n", row); \ error = 1; \ break; \ } @@ -426,7 +450,7 @@ NSTiffWrite(TIFF* image, NSTiffInfo* info, char* data) tdata_t buf = (tdata_t)data; int i; int row; - int error = 0; + int error = 0; TIFFSetField(image, TIFFTAG_IMAGEWIDTH, info->width); TIFFSetField(image, TIFFTAG_IMAGELENGTH, info->height); @@ -470,7 +494,6 @@ NSTiffWrite(TIFF* image, NSTiffInfo* info, char* data) case PHOTOMETRIC_RGB: if (info->planarConfig == PLANARCONFIG_CONTIG) { - NSDebugLLog(@"NSImage", @"PHOTOMETRIC_RGB: CONTIG\n"); for (row = 0; row < info->height; ++row) { WRITE_SCANLINE(0) @@ -479,7 +502,6 @@ NSTiffWrite(TIFF* image, NSTiffInfo* info, char* data) } else { - NSDebugLLog(@"NSImage", @"PHOTOMETRIC_RGB: NOT CONTIG\n"); for (i = 0; i < info->samplesPerPixel; i++) { for (row = 0; row < info->height; ++row) @@ -492,12 +514,13 @@ NSTiffWrite(TIFF* image, NSTiffInfo* info, char* data) break; default: - TIFFError(TIFFFileName(image), - "Can't write photometric %d", info->photoInterp); + NSLog(@"Tiff can't write photometric %d for image %s", + info->photoInterp, TIFFFileName(image)); + return -1; break; } - return error; + return 0; } /*------------------------------------------------------------------------*/