// Copyright 1996-1998 Omni Development, Inc.  All rights reserved.
//
// This software may only be used and reproduced according to the
// terms in the file OmniSourceLicense.html, which should be
// distributed with this project and can also be found at
// http://www.omnigroup.com/DeveloperResources/OmniSourceLicense.html.

#import "OIGifColorTable.h"

#import <Foundation/Foundation.h>
#import <OmniBase/OmniBase.h>
#import <OmniFoundation/OmniFoundation.h>
#import <OWF/OWF.h>
#import <OIF/OIF.h>
#import <math.h>

#import "OIGifImageProcessor.h"

RCS_ID("$Header: /Network/Developer/Source/CVS/OmniGroup/OmniComponents/ImageProcessors/gif/OIGifColorTable.m,v 1.4 1998/12/10 21:21:41 kc Exp $")

@implementation OIGifColorTable

static OIGifColor transparentColorValues;

+ (void)initialize;
{
    static BOOL initialized = NO;

    [super initialize];
    if (initialized)
	return;
    initialized = YES;

    transparentColorValues.components.red = 0;
    transparentColorValues.components.green = 0;
    transparentColorValues.components.blue = 0;
    transparentColorValues.components.alpha = 0;
}

static inline OIGifColor OIMakeGifColor(byte red, byte green, byte blue, byte alpha)
{
    OIGifColor gifColor;

    gifColor.components.red = red;
    gifColor.components.green = green;
    gifColor.components.blue = blue;
    gifColor.components.alpha = alpha;

    return gifColor;
}

static inline byte
applyGamma(byte sample, double gamma)
{
    return pow(((double)sample / 255.0), gamma) * 255;
}


- initFromDataStreamCursor:(OWDataStreamCursor *)dataCursor size:(unsigned int)newSize gamma:(float)gamma;
{
    unsigned int colorIndex;
	
    if (![super init])
        return nil;
    
    transparentColorIndex = -1;
    
    if (newSize) {
	byte rgbBuffer[newSize * 3];
	byte *colorComponent;
	OIGifColor *colorTableEntry, *colorTableEnd;

	size = newSize;
	[dataCursor readBytes:size * 3 intoBuffer:rgbBuffer];
	colorComponent = rgbBuffer;
	colorTableEntry = colorTable;
	colorTableEnd = colorTable + size;
	while (colorTableEntry < colorTableEnd) {
	    colorTableEntry->components.red = *(colorComponent++);
	    colorTableEntry->components.green = *(colorComponent++);
	    colorTableEntry->components.blue = *(colorComponent++);
	    colorTableEntry->components.alpha = 255;
	    colorTableEntry++;
	}
    } else {
	size = 2;
	colorTable[0] = OIMakeGifColor(0, 0, 0, 255);
	colorTable[1] = OIMakeGifColor(255, 255, 255, 255);
    }
    
    // Fill the rest of the table with RED to be really clear
    for (colorIndex = size; colorIndex < OIGifColorTableMaxEntries; colorIndex++)
	colorTable[colorIndex] = OIMakeGifColor(255, 0, 0, 255);

    // Apply gamma correction if it is set
    if (gamma != 1.0 && gamma != 0.0) {
	colorIndex = size;
	while (colorIndex--) {
	    colorTable[colorIndex].components.red =
		    applyGamma(colorTable[colorIndex].components.red, gamma);
	    colorTable[colorIndex].components.green =
		    applyGamma(colorTable[colorIndex].components.green, gamma);
	    colorTable[colorIndex].components.blue =
		    applyGamma(colorTable[colorIndex].components.blue, gamma);
	}
    }
    return self;
}

- (unsigned int)size;
{
    return size;
}

- (void)setTransparentColorIndex:(short int)anIndex;
{
    if (transparentColorIndex == anIndex)
	return;
    if (transparentColorIndex >= 0 && transparentColorIndex < 256)
	colorTable[transparentColorIndex].packed = oldTransparentColorValues.packed;
    transparentColorIndex = anIndex;
    if (transparentColorIndex >= 0 && transparentColorIndex < 256) {
	oldTransparentColorValues.packed = colorTable[transparentColorIndex].packed;
	colorTable[transparentColorIndex].packed = transparentColorValues.packed;
    }
}

- (short int)transparentColorIndex;
{
    return transparentColorIndex;
}

@end
