/*$Copyright:
 * Copyright (C) 1992.5.22. Recruit Co.,Ltd. 
 * Institute for Supercomputing Research
 * All rights reserved.
 * NewsBase  by ISR, Kazuto MIYAI, Gary ARAKAKI, Katsunori SUZUKI, Kok-meng Lue
 *
 * You may freely copy, distribute and reuse the code in this program under 
 * following conditions.
 * - to include this notice in the source code, if it is to be distributed 
 *   with source code.
 * - to add the file named "COPYING" within the code, which shall include 
 *   GNU GENERAL PUBLIC LICENSE(*).
 * - to display an acknowledgement in binary code as follows: "This product
 *   includes software developed by Recruit Co.,Ltd., ISR."
 * - to display a notice which shall state that the users may freely copy,
 *   distribute and reuse the code in this program under GNU GENERAL PUBLIC
 *   LICENSE(*)
 * - to indicate the way to access the copy of GNU GENERAL PUBLIC LICENSE(*)
 *
 *   (*)GNU GENERAL PUBLIC LICENSE is stored in the file named COPYING
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
$*/

// ITiffD is the media class for TIFF.  The file extension, RTF control word
// and pasteboard type are "tiff", "MMtiff" and NXTIFFPboardtype respectively.

#import "ITiffD.h"
#import <appkit/NXImage.h>
#import <appkit/Pasteboard.h>
#import <appkit/NXBitmapImageRep.h>
#import "errdebug.h"

@implementation ITiffD

static NXAtom fileExtension;
static NXImage *icon;

+ initialize
{
    fileExtension = NXUniqueStringNoCopy("tiff");
    [IMediaD getFileIconFor:(Class)self];
    return(self);
}

+ (NXAtom)fileExtension
{
    return(fileExtension);
}

+ (NXAtom)pasteboardType
{
    return(NXTIFFPboardType);
}

+ setIcon:(NXImage *)theIcon
{
    icon = theIcon;
    return(self);
}

+ (NXImage *)icon
{
    return(icon);
}

- initWithKey:(char *)pathName
{
    [super initWithKey:pathName];
    image = nil;
    twoBitData = NULL;
    return(self);
}

- (NXImage *)image 
{
    return(image);
}

- (BOOL)readFromStream:(NXStream *)inStream
{
    NXBitmapImageRep *bitmap;
    NXSize imageSize;

    [super readFromStream:inStream];
    if ((bitmap = [[NXBitmapImageRep allocFromZone:[self zone]]
        initFromStream:stream]) != nil) {
        NXSeek(stream, (long)0, NX_FROMSTART);
        imageSize.width = [bitmap pixelsWide];
        imageSize.height = [bitmap pixelsHigh];
        image = [[NXImage allocFromZone:[self zone]] setSize:&imageSize];
        [image useCacheWithDepth:NX_TwentyFourBitRGBDepth];
        [image setDataRetained:YES];
        [image lockFocus];
        [bitmap draw];
        [image unlockFocus];
        [bitmap free];
        return(YES);
    } else {
        return(NO);
    }
}

- free
{
    if (image != nil) {
        [image free];
    }
    if (twoBitData != NULL) {
        NXZoneFree([self zone], twoBitData);
    }
    return([super free]);
}

- addTwoBitGrayRepresentation
{
    NXRect		rect;
    NXImage		*convertedImage;
    NXBitmapImageRep	*convertedBitmap;
    NXBitmapImageRep	*twoBitBitmap;
    unsigned char	*sptr, *tptr;
    int			x, y;

    [image getSize:&rect.size];
    rect.origin.x = rect.origin.y = 0.0;
    rect.size.width = rect.size.width / 4 * 4;
    convertedImage = [[NXImage alloc] initSize:&rect.size];
    [convertedImage useCacheWithDepth:NX_EightBitGrayDepth];
    [convertedImage lockFocusOn:[convertedImage lastRepresentation]];
    [[image lastRepresentation] draw];
    convertedBitmap = [[NXBitmapImageRep alloc] initData:NULL fromRect:&rect];
    [convertedImage unlockFocus];
    [convertedImage free];
    convertedImage = nil;
    if ([convertedBitmap bitsPerPixel] != 8) {
        [convertedBitmap free];
        convertedBitmap = nil;
        twoBitData = NULL;
        return self;
    }
    twoBitData = NXZoneMalloc([self zone],
        (int)rect.size.width * (int)rect.size.height / 4);
    sptr = [convertedBitmap data], tptr = twoBitData;
    for (y = 0; y < rect.size.height; ++y) {
        for (x = 0; x < rect.size.width; x += 4, sptr += 4, tptr += 1) {
            *tptr = ((*(sptr + 0) & 0xc0) >> 0) |
                    ((*(sptr + 1) & 0xc0) >> 2) |
                    ((*(sptr + 2) & 0xc0) >> 4) |
                    ((*(sptr + 3) & 0xc0) >> 6);
        }
    }
    [convertedBitmap free];
    convertedBitmap = nil;
    twoBitBitmap = [[NXBitmapImageRep alloc]
        initData:twoBitData pixelsWide:(int)rect.size.width
        pixelsHigh:(int)rect.size.height bitsPerSample:2
        samplesPerPixel:1 hasAlpha:NO isPlanar:YES
        colorSpace:NX_OneIsWhiteColorSpace
        bytesPerRow:((int)rect.size.width * 2 + 7) / 8 bitsPerPixel:2];
    [image useRepresentation:twoBitBitmap];
    return(self);
}

@end
