From 4fd327af6b08b7852b8b6e8851d565a7eeaf05e0 Mon Sep 17 00:00:00 2001 From: Jens Ayton Date: Sun, 16 May 2010 13:17:38 +0000 Subject: [PATCH] Replaced OOPixMap.components with saner OOPixMap.format. git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3362 127b21dd-08f5-0310-b4b7-95ae10353056 --- .../OOCombinedEmissionMapGenerator.m | 22 +-- src/Core/Materials/OOConcreteTexture.m | 9 +- src/Core/Materials/OOPixMap.h | 40 ++++- src/Core/Materials/OOPixMap.m | 99 +++++++++--- .../Materials/OOPixMapChannelOperations.h | 14 +- .../Materials/OOPixMapChannelOperations.m | 57 ++++--- src/Core/Materials/OOTexture.h | 11 +- src/Core/Materials/OOTextureLoader.m | 4 +- src/Core/OOConvertCubeMapToLatLong.m | 2 +- src/Core/OONSOperation.h | 7 +- src/Core/OOTextureScaling.h | 9 +- src/Core/OOTextureScaling.m | 142 ++++++++++-------- 12 files changed, 254 insertions(+), 162 deletions(-) diff --git a/src/Core/Materials/OOCombinedEmissionMapGenerator.m b/src/Core/Materials/OOCombinedEmissionMapGenerator.m index 39230e18..bf441331 100644 --- a/src/Core/Materials/OOCombinedEmissionMapGenerator.m +++ b/src/Core/Materials/OOCombinedEmissionMapGenerator.m @@ -258,7 +258,7 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB); if (haveEmission) DUMP(_emissionPx, @"source emission map"); // Extract illumination component if emission_and_illumination_map. - if (haveEmission && _isCombinedMap && _emissionPx.components > 1) + if (haveEmission && _isCombinedMap && OOPixMapFormatHasAlpha(_emissionPx.format)) { OOPixMapToRGBA(&_emissionPx); illuminationPx = OODuplicatePixMap(_emissionPx, 0); @@ -332,24 +332,8 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB); _width = _emissionPx.width; _height = _emissionPx.height; _rowBytes = _emissionPx.rowBytes; - switch (_emissionPx.components) - { - case 1: - _format = kOOTextureDataGrayscale; - break; - - case 2: - _format = kOOTextureDataGrayscaleAlpha; - break; - - case 4: - _format = kOOTextureDataRGBA; - break; - - default: - OOLogERR(@"texture.combinedEmissionMap.error", @"Unexepected component count %u for %@", _emissionPx.components, self); - _data = NULL; - } + _format = _emissionPx.format; + _emissionPx.pixels = NULL; // So it won't be freed by -dealloc. } if (_data == NULL) diff --git a/src/Core/Materials/OOConcreteTexture.m b/src/Core/Materials/OOConcreteTexture.m index 517678ad..e8e1fd02 100644 --- a/src/Core/Materials/OOConcreteTexture.m +++ b/src/Core/Materials/OOConcreteTexture.m @@ -256,12 +256,11 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o [self ensureFinishedLoading]; OOPixMap px = kOONullPixMap; - OOPixMapComponentCount components = OOTextureComponentsForFormat(_format); if (_bytes != NULL) { // If possible, just copy our existing buffer. - px = OOMakePixMap(_bytes, _width, _height, components, 0, 0); + px = OOMakePixMap(_bytes, _width, _height, _format, 0, 0); px = OODuplicatePixMap(px, 0); } #if OOTEXTURE_RELOADABLE @@ -276,7 +275,7 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o if (![self isCubeMap]) { - px = OOAllocatePixMap(_width, _height, components, 0, 0); + px = OOAllocatePixMap(_width, _height, _format, 0, 0); if (!OOIsValidPixMap(px)) return kOONullPixMap; glGetTexImage(GL_TEXTURE_2D, 0, format, type, px.pixels); @@ -284,7 +283,7 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o #if OO_TEXTURE_CUBE_MAP else { - px = OOAllocatePixMap(_width, _width * 6, components, 0, 0); + px = OOAllocatePixMap(_width, _width * 6, _format, 0, 0); if (!OOIsValidPixMap(px)) return kOONullPixMap; uint8_t *pixels = px.pixels; @@ -292,7 +291,7 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o for (i = 0; i < 6; i++) { glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format, type, pixels); - pixels += components * _width * _width; + pixels += OOPixMapBytesPerPixelForFormat(_format) * _width * _width; } } #endif diff --git a/src/Core/Materials/OOPixMap.h b/src/Core/Materials/OOPixMap.h index c144c441..0678aa7b 100644 --- a/src/Core/Materials/OOPixMap.h +++ b/src/Core/Materials/OOPixMap.h @@ -31,14 +31,23 @@ SOFTWARE. typedef uint_fast32_t OOPixMapDimension; // Note: dimensions are assumed to be less than 1048576 (2^20) pixels. -typedef uint_fast8_t OOPixMapComponentCount; // Currently supported values are 1, 2 and 4. +//typedef uint_fast8_t OOPixMapComponentCount; // Currently supported values are 1, 2 and 4. + + +typedef enum +{ + kOOPixMapInvalidFormat = 0, + kOOPixMapGrayscale = 1, + kOOPixMapGrayscaleAlpha = 2, + kOOPixMapRGBA = 4 +} OOPixMapFormat; typedef struct OOPixMap { void *pixels; OOPixMapDimension width, height; - OOPixMapComponentCount components; + OOPixMapFormat format; size_t rowBytes; size_t bufferSize; } OOPixMap; @@ -57,13 +66,13 @@ OOINLINE size_t OOMinimumPixMapBufferSize(OOPixMap pixMap) { return pixMap.rowB invalid. If rowBytes or bufferSize are zero, minimum valid values will be used. */ -OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount components, size_t rowBytes, size_t bufferSize); +OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize); /* OOAllocatePixMap() Create an OOPixMap, allocating storage. If rowBytes or bufferSize are zero, minimum valid values will be used. */ -OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount components, size_t rowBytes, size_t bufferSize); +OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize); /* OOFreePixMap() @@ -104,3 +113,26 @@ void OODumpPixMap(OOPixMap pixMap, NSString *name); #else #define OODumpPixMap(p, n) do {} while (0) #endif + + +BOOL OOIsValidPixMapFormat(OOPixMapFormat format); + + +#ifndef NDEBUG +size_t OOPixMapBytesPerPixelForFormat(OOPixMapFormat format) PURE_FUNC; +#else +OOINLINE size_t OOPixMapBytesPerPixelForFormat(OOPixMapFormat format) +{ + // Currently, format values are component counts. This is subject to change. + return format; +} +#endif + +OOINLINE size_t OOPixMapBytesPerPixel(OOPixMap pixMap) +{ + return OOPixMapBytesPerPixelForFormat(pixMap.format); +} + +NSString *OOPixMapFormatName(OOPixMapFormat format) PURE_FUNC; + +BOOL OOPixMapFormatHasAlpha(OOPixMapFormat format) PURE_FUNC; diff --git a/src/Core/Materials/OOPixMap.m b/src/Core/Materials/OOPixMap.m index 2b422e16..83c283b3 100644 --- a/src/Core/Materials/OOPixMap.m +++ b/src/Core/Materials/OOPixMap.m @@ -33,7 +33,7 @@ const OOPixMap kOONullPixMap = .pixels = NULL, .width = 0, .height = 0, - .components = 0, + .format = kOOPixMapInvalidFormat, .rowBytes = 0, .bufferSize = 0 }; @@ -44,15 +44,15 @@ BOOL OOIsValidPixMap(OOPixMap pixMap) return pixMap.pixels != NULL && pixMap.width > 0 && pixMap.height > 0 && - (pixMap.components == 1 || pixMap.components == 2 || pixMap.components == 4) && - pixMap.rowBytes >= pixMap.width * pixMap.components && + OOIsValidPixMapFormat(pixMap.format) && + pixMap.rowBytes >= pixMap.width * OOPixMapBytesPerPixelForFormat(pixMap.format) && pixMap.bufferSize >= pixMap.rowBytes * pixMap.height; } -OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount components, size_t rowBytes, size_t bufferSize) +OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize) { - if (rowBytes == 0) rowBytes = width * components; + if (rowBytes == 0) rowBytes = width * OOPixMapBytesPerPixelForFormat(format); if (bufferSize == 0) bufferSize = rowBytes * height; OOPixMap result = @@ -60,7 +60,7 @@ OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension h .pixels = pixels, .width = width, .height = height, - .components = components, + .format = format, .rowBytes = rowBytes, .bufferSize = bufferSize }; @@ -70,10 +70,10 @@ OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension h } -OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount components, size_t rowBytes, size_t bufferSize) +OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize) { // Create pixmap struct with dummy pixel pointer to test validity. - OOPixMap pixMap = OOMakePixMap((void *)-1, width, height, components, rowBytes, bufferSize); + OOPixMap pixMap = OOMakePixMap((void *)-1, width, height, format, rowBytes, bufferSize); if (EXPECT_NOT(!OOIsValidPixMap(pixMap))) return kOONullPixMap; pixMap.pixels = malloc(pixMap.bufferSize); @@ -99,7 +99,7 @@ OOPixMap OODuplicatePixMap(OOPixMap srcPixMap, size_t desiredSize) size_t minSize = OOMinimumPixMapBufferSize(srcPixMap); if (desiredSize < minSize) desiredSize = minSize; - OOPixMap result = OOAllocatePixMap(srcPixMap.width, srcPixMap.width, srcPixMap.components, srcPixMap.rowBytes, desiredSize); + OOPixMap result = OOAllocatePixMap(srcPixMap.width, srcPixMap.width, srcPixMap.format, srcPixMap.rowBytes, desiredSize); if (EXPECT_NOT(!OOIsValidPixMap(result))) return kOONullPixMap; memcpy(result.pixels, srcPixMap.pixels, minSize); @@ -148,9 +148,13 @@ void OODumpPixMap(OOPixMap pixMap, NSString *name) MyOpenGLView *gameView = [UNIVERSE gameView]; - switch (pixMap.components) + switch (pixMap.format) { - case 1: + + case kOOPixMapInvalidFormat: + break; + + case kOOPixMapGrayscale: [gameView dumpGrayToFileNamed:name bytes:pixMap.pixels width:pixMap.width @@ -158,7 +162,7 @@ void OODumpPixMap(OOPixMap pixMap, NSString *name) rowBytes:pixMap.rowBytes]; break; - case 2: + case kOOPixMapGrayscaleAlpha: [gameView dumpGrayAlphaToFileNamed:name bytes:pixMap.pixels width:pixMap.width @@ -166,15 +170,7 @@ void OODumpPixMap(OOPixMap pixMap, NSString *name) rowBytes:pixMap.rowBytes]; break; - case 3: - [gameView dumpRGBAToFileNamed:name - bytes:pixMap.pixels - width:pixMap.width - height:pixMap.height - rowBytes:pixMap.rowBytes]; - break; - - case 4: + case kOOPixMapRGBA: [gameView dumpRGBAToRGBFileNamed:[name stringByAppendingString:@" rgb"] andGrayFileNamed:[name stringByAppendingString:@" alpha"] bytes:pixMap.pixels @@ -184,5 +180,64 @@ void OODumpPixMap(OOPixMap pixMap, NSString *name) break; } } - #endif + + +BOOL OOIsValidPixMapFormat(OOPixMapFormat format) +{ + switch (format) + { + case kOOPixMapInvalidFormat: return NO; + case kOOPixMapGrayscale: + case kOOPixMapGrayscaleAlpha: + case kOOPixMapRGBA: + return YES; + } + + return NO; +} + + +#ifndef NDEBUG +size_t OOPixMapBytesPerPixelForFormat(OOPixMapFormat format) +{ + switch (format) + { + case kOOPixMapInvalidFormat: return 0; + case kOOPixMapGrayscale: return 1; + case kOOPixMapGrayscaleAlpha: return 2; + case kOOPixMapRGBA: return 4; + } + + return -1; +} +#endif + + +NSString *OOPixMapFormatName(OOPixMapFormat format) +{ + switch (format) + { + case kOOPixMapInvalidFormat: return @"invalid"; + case kOOPixMapGrayscale: return @"grayscale"; + case kOOPixMapGrayscaleAlpha: return @"grayscale+alpha"; + case kOOPixMapRGBA: return @"RGBA"; + } + + return [NSString stringWithFormat:@"invalid<%i>", (int)format]; +} + + + +BOOL OOPixMapFormatHasAlpha(OOPixMapFormat format) +{ + switch (format) + { + case kOOPixMapInvalidFormat: return NO; + case kOOPixMapGrayscale: return NO; + case kOOPixMapGrayscaleAlpha: return YES; + case kOOPixMapRGBA: return YES; + } + + return NO; +} diff --git a/src/Core/Materials/OOPixMapChannelOperations.h b/src/Core/Materials/OOPixMapChannelOperations.h index a171f282..7e5121d9 100644 --- a/src/Core/Materials/OOPixMapChannelOperations.h +++ b/src/Core/Materials/OOPixMapChannelOperations.h @@ -40,21 +40,19 @@ SOFTWARE. pixmap, a pixmap whose channel count is not 4, or a channel index greater than 3. */ -BOOL OOExtractPixMapChannel(OOPixMap *ioPixMap, OOPixMapComponentCount channelIndex, BOOL compactWhenDone); +BOOL OOExtractPixMapChannel(OOPixMap *ioPixMap, uint8_t channelIndex, BOOL compactWhenDone); /* OOPixMapToRGBA() - Convert a pixmap to RGBA format. If it has one component, it is assumed to - be greyscale. If it has two components, it is assumed to be greyscale+alpha. - If it has four components, it is left as-is. + Convert a pixmap to RGBA format. NOTE: if successful, this will free() the original buffer and replace it. */ BOOL OOPixMapToRGBA(OOPixMap *ioPixMap); /* OOPixMapModulateUniform() - Multiply all pixels by specified per-component factors. Pixmap must have - four components. The effect of using factors outside the range [0..1] is + Multiply all pixels by specified per-component factors. Pixmap must be in + RGBA format. The effect of using factors outside the range [0..1] is undefined. OOPixMapToRGBA() is called on ioPixMap. */ @@ -64,7 +62,7 @@ BOOL OOPixMapModulateUniform(OOPixMap *ioPixMap, float f0, float f1, float f2, f /* OOPixMapModulatePixMap() Multiply each pixel of ioDstPixMap by the corresponding pixel of otherPixMap, writing the result to ioDstPixMap. - OOPixMapToRGBA() is called on ioDstPixMap; otherPixMap must have four components. + OOPixMapToRGBA() is called on ioDstPixMap; otherPixMap must be RGBA. */ BOOL OOPixMapModulatePixMap(OOPixMap *ioDstPixMap, OOPixMap otherPixMap); @@ -72,6 +70,6 @@ BOOL OOPixMapModulatePixMap(OOPixMap *ioDstPixMap, OOPixMap otherPixMap); /* OOPixMapAddPixMap() Add each pixel of otherPixMap to the corresponding pixel of ioDstPixMap, writing the result to ioDstPixMap. - OOPixMapToRGBA() is called on ioDstPixMap; otherPixMap must have four components. + OOPixMapToRGBA() is called on ioDstPixMap; otherPixMap must be RGBA. */ BOOL OOPixMapAddPixMap(OOPixMap *ioDstPixMap, OOPixMap otherPixMap); diff --git a/src/Core/Materials/OOPixMapChannelOperations.m b/src/Core/Materials/OOPixMapChannelOperations.m index 35219f4c..f3c523cd 100644 --- a/src/Core/Materials/OOPixMapChannelOperations.m +++ b/src/Core/Materials/OOPixMapChannelOperations.m @@ -29,7 +29,7 @@ SOFTWARE. #import "OOCPUInfo.h" -static void ExtractChannel_4(OOPixMap *ioPixMap, OOPixMapComponentCount channelIndex); +static void ExtractChannel_4(OOPixMap *ioPixMap, uint8_t channelIndex); static void ToRGBA_1(OOPixMap srcPx, OOPixMap dstPx); static void ToRGBA_2(OOPixMap srcPx, OOPixMap dstPx); static void ModulateUniform_4(OOPixMap pixMap, uint16_t f0, uint16_t f1, uint16_t f2, uint16_t f3); @@ -37,16 +37,16 @@ static void ModulatePixMap_4(OOPixMap mainPx, OOPixMap otherPx); static void AddPixMap_4(OOPixMap mainPx, OOPixMap otherPx); -BOOL OOExtractPixMapChannel(OOPixMap *ioPixMap, OOPixMapComponentCount channelIndex, BOOL compactWhenDone) +BOOL OOExtractPixMapChannel(OOPixMap *ioPixMap, uint8_t channelIndex, BOOL compactWhenDone) { - if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap) || ioPixMap->components != 4 || channelIndex > 3)) + if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap) || ioPixMap->format != kOOPixMapRGBA || channelIndex > 3)) { return NO; } ExtractChannel_4(ioPixMap, channelIndex); - ioPixMap->components = 1; + ioPixMap->format = kOOPixMapGrayscale; ioPixMap->rowBytes = ioPixMap->width; if (compactWhenDone) @@ -58,7 +58,7 @@ BOOL OOExtractPixMapChannel(OOPixMap *ioPixMap, OOPixMapComponentCount channelIn } -static void ExtractChannel_4(OOPixMap *ioPixMap, OOPixMapComponentCount channelIndex) +static void ExtractChannel_4(OOPixMap *ioPixMap, uint8_t channelIndex) { NSCParameterAssert(ioPixMap != NULL); @@ -96,25 +96,46 @@ static void ExtractChannel_4(OOPixMap *ioPixMap, OOPixMapComponentCount channelI BOOL OOPixMapToRGBA(OOPixMap *ioPixMap) { if (EXPECT_NOT(ioPixMap == NULL || !OOIsValidPixMap(*ioPixMap))) return NO; - - if (ioPixMap->components == 4) return YES; - if (EXPECT_NOT(ioPixMap->components != 1 && ioPixMap->components != 2)) return NO; + if (ioPixMap->format == kOOPixMapRGBA) return YES; OOPixMap temp = OOAllocatePixMap(ioPixMap->width, ioPixMap->height, 4, 0, 0); if (EXPECT_NOT(OOIsNullPixMap(temp))) return NO; - if (ioPixMap->components == 1) ToRGBA_1(*ioPixMap, temp); - else if (ioPixMap->components == 2) ToRGBA_2(*ioPixMap, temp); + BOOL OK = NO; + switch (ioPixMap->format) + { + case kOOPixMapGrayscale: + ToRGBA_1(*ioPixMap, temp); + break; + + case kOOPixMapGrayscaleAlpha: + ToRGBA_2(*ioPixMap, temp); + break; + + case kOOPixMapRGBA: + case kOOPixMapInvalidFormat: + OK = NO; + break; + // No default, because -Wswitch-enum is our friend. + } - free(ioPixMap->pixels); - *ioPixMap = temp; - return YES; + if (OK) + { + free(ioPixMap->pixels); + *ioPixMap = temp; + } + else + { + free(temp.pixels); + } + + return OK; } static void ToRGBA_1(OOPixMap srcPx, OOPixMap dstPx) { - NSCParameterAssert(srcPx.components == 1 && dstPx.components == 4 && srcPx.width == dstPx.width && srcPx.height == dstPx.height); + NSCParameterAssert(OOPixMapBytesPerPixel(srcPx) == 1 && dstPx.format == kOOPixMapRGBA && srcPx.width == dstPx.width && srcPx.height == dstPx.height); uint8_t *src; uint32_t *dst; @@ -145,7 +166,7 @@ static void ToRGBA_1(OOPixMap srcPx, OOPixMap dstPx) static void ToRGBA_2(OOPixMap srcPx, OOPixMap dstPx) { - NSCParameterAssert(srcPx.components == 2 && dstPx.components == 4 && srcPx.width == dstPx.width && srcPx.height == dstPx.height); + NSCParameterAssert(OOPixMapBytesPerPixel(srcPx) == 2 && dstPx.format == kOOPixMapRGBA && srcPx.width == dstPx.width && srcPx.height == dstPx.height); uint16_t *src; uint_fast32_t px; @@ -196,7 +217,7 @@ static void ModulateUniform_4(OOPixMap pixMap, uint16_t f3, uint16_t f2, uint16_ #error Unknown byte order. #endif { - NSCParameterAssert(pixMap.components == 4); + NSCParameterAssert(OOPixMapBytesPerPixel(pixMap) == 4); uint32_t *curr; uint_fast32_t px; @@ -243,7 +264,7 @@ static void ModulateUniform_4(OOPixMap pixMap, uint16_t f3, uint16_t f2, uint16_ BOOL OOPixMapModulatePixMap(OOPixMap *ioDstPixMap, OOPixMap otherPixMap) { if (EXPECT_NOT(ioDstPixMap == NULL || !OOIsValidPixMap(*ioDstPixMap))) return NO; - if (EXPECT_NOT(!OOIsValidPixMap(otherPixMap) || otherPixMap.components != 4)) return NO; + if (EXPECT_NOT(!OOIsValidPixMap(otherPixMap) || otherPixMap.format != kOOPixMapRGBA)) return NO; if (EXPECT_NOT(!OOPixMapToRGBA(ioDstPixMap))) return NO; if (EXPECT_NOT(ioDstPixMap->width != otherPixMap.width || ioDstPixMap->height != otherPixMap.height)) return NO; @@ -302,7 +323,7 @@ static void ModulatePixMap_4(OOPixMap mainPx, OOPixMap otherPx) BOOL OOPixMapAddPixMap(OOPixMap *ioDstPixMap, OOPixMap otherPixMap) { if (EXPECT_NOT(ioDstPixMap == NULL || !OOIsValidPixMap(*ioDstPixMap))) return NO; - if (EXPECT_NOT(!OOIsValidPixMap(otherPixMap) || otherPixMap.components != 4)) return NO; + if (EXPECT_NOT(!OOIsValidPixMap(otherPixMap) || otherPixMap.format != kOOPixMapRGBA)) return NO; if (EXPECT_NOT(!OOPixMapToRGBA(ioDstPixMap))) return NO; if (EXPECT_NOT(ioDstPixMap->width != otherPixMap.width || ioDstPixMap->height != otherPixMap.height)) return NO; diff --git a/src/Core/Materials/OOTexture.h b/src/Core/Materials/OOTexture.h index 667a161d..17c21b94 100644 --- a/src/Core/Materials/OOTexture.h +++ b/src/Core/Materials/OOTexture.h @@ -34,6 +34,7 @@ SOFTWARE. #import #import "OOOpenGL.h" +#import "OOPixMap.h" #import "OOWeakReference.h" @class OOTextureLoader, OOTextureGenerator; @@ -95,11 +96,11 @@ enum typedef enum { - kOOTextureDataInvalid, + kOOTextureDataInvalid = kOOPixMapInvalidFormat, - kOOTextureDataRGBA, // GL_RGBA - kOOTextureDataGrayscale, // GL_LUMINANCE (or GL_ALPHA with kOOTextureAlphaMask) - kOOTextureDataGrayscaleAlpha // GL_LUMINANCE_ALPHA + kOOTextureDataRGBA = kOOPixMapRGBA, // GL_RGBA + kOOTextureDataGrayscale = kOOPixMapGrayscale, // GL_LUMINANCE (or GL_ALPHA with kOOTextureAlphaMask) + kOOTextureDataGrayscaleAlpha = kOOPixMapGrayscaleAlpha // GL_LUMINANCE_ALPHA } OOTextureDataFormat; @@ -190,7 +191,7 @@ typedef enum /* Create a new pixmap with a copy of the texture data. The caller is responsible for free()ing the resulting buffer. */ -- (struct OOPixMap) copyPixMapRepresentation; +- (OOPixMap) copyPixMapRepresentation; /* Identify special texture types. */ diff --git a/src/Core/Materials/OOTextureLoader.m b/src/Core/Materials/OOTextureLoader.m index 58a77dd7..f3fa99ba 100644 --- a/src/Core/Materials/OOTextureLoader.m +++ b/src/Core/Materials/OOTextureLoader.m @@ -336,7 +336,7 @@ static BOOL sHaveSetUp = NO; void *dstBytes = ((uint8_t *)newData) + newSideSize * i; memcpy(dstBytes, srcBytes, srcSideSize); - OOGenerateMipMaps(dstBytes, _width, _width, components); + OOGenerateMipMaps(dstBytes, _width, _width, _format); } free(_data); @@ -434,7 +434,7 @@ static BOOL sHaveSetUp = NO; } if (_generateMipMaps) { - OOGenerateMipMaps(_data, _width, _height, components); + OOGenerateMipMaps(_data, _width, _height, _format); } // All done. diff --git a/src/Core/OOConvertCubeMapToLatLong.m b/src/Core/OOConvertCubeMapToLatLong.m index f258ea46..f64b3a1c 100644 --- a/src/Core/OOConvertCubeMapToLatLong.m +++ b/src/Core/OOConvertCubeMapToLatLong.m @@ -36,7 +36,7 @@ SOFTWARE. OOPixMap OOConvertCubeMapToLatLong(OOPixMap sourcePixMap, OOPixMapDimension height, BOOL leaveSpaceForMipMaps) { - if (!OOIsValidPixMap(sourcePixMap) || sourcePixMap.components != 4 || sourcePixMap.height != sourcePixMap.width * 6) + if (!OOIsValidPixMap(sourcePixMap) || sourcePixMap.format != kOOPixMapRGBA || sourcePixMap.height != sourcePixMap.width * 6) { return kOONullPixMap; } diff --git a/src/Core/OONSOperation.h b/src/Core/OONSOperation.h index f42c0635..4cdf9855 100644 --- a/src/Core/OONSOperation.h +++ b/src/Core/OONSOperation.h @@ -6,16 +6,11 @@ -- Ahruman 2009-09-04 */ -#define OO_HAVE_NSOPERATION 0 #ifndef OO_HAVE_NSOPERATION #if OOLITE_MAC_OS_X #define OO_HAVE_NSOPERATION OOLITE_LEOPARD #elif OOLITE_GNUSTEP - #ifdef __NSOperation_h_GNUSTEP_BASE_INCLUDE - #if OS_API_VERSION(100500, GS_API_LATEST) - #define OO_HAVE_NSOPERATION 1 - #endif - #endif + #define OO_HAVE_NSOPERATION OOLITE_GNUSTEP_1_20 && OS_API_VERSION(100500, GS_API_LATEST) #endif #endif diff --git a/src/Core/OOTextureScaling.h b/src/Core/OOTextureScaling.h index 4ce0f97e..68a06fb8 100644 --- a/src/Core/OOTextureScaling.h +++ b/src/Core/OOTextureScaling.h @@ -40,15 +40,8 @@ SOFTWARE. */ OOPixMap OOScalePixMap(OOPixMap srcPixMap, OOPixMapDimension dstWidth, OOPixMapDimension dstHeight, BOOL leaveSpaceForMipMaps); -OOINLINE void *OOScalePixMapRaw(void *srcData, OOPixMapDimension srcWidth, OOPixMapDimension srcHeight, OOPixMapComponentCount components, size_t srcRowBytes, OOPixMapDimension dstWidth, OOPixMapDimension dstHeight, BOOL leaveSpaceForMipMaps) -{ - OOPixMap src = OOMakePixMap(srcData, srcWidth, srcHeight, components, srcRowBytes, 0); - OOPixMap dst = OOScalePixMap(src, dstWidth, dstHeight, leaveSpaceForMipMaps); - return dst.pixels; -} - /* Assumes 8 bits per sample, interleaved. Buffer must have space for (4 * width * height) / 3 pixels. */ -BOOL OOGenerateMipMaps(void *textureBytes, OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount planes); +BOOL OOGenerateMipMaps(void *textureBytes, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format); diff --git a/src/Core/OOTextureScaling.m b/src/Core/OOTextureScaling.m index 9a9bebb8..04144aab 100644 --- a/src/Core/OOTextureScaling.m +++ b/src/Core/OOTextureScaling.m @@ -128,81 +128,87 @@ OOINLINE void StretchVertically(OOPixMap srcPx, OOPixMap dstPx) OOINLINE void SqueezeVertically(OOPixMap pixMap, OOPixMapDimension dstHeight) { - switch (pixMap.components) + switch (pixMap.format) { - case 4: + case kOOPixMapRGBA: SqueezeVertically4(pixMap, dstHeight); - break; + return; - case 1: + case kOOPixMapGrayscale: SqueezeVertically1(pixMap, dstHeight); - break; + return; - case 2: + case kOOPixMapGrayscaleAlpha: SqueezeVertically2(pixMap, dstHeight); - break; + return; -#ifndef NDEBUG - default: - [NSException raise:NSInternalInconsistencyException format:@"Invalid texture component count: %u", pixMap.components]; -#else - abort(); -#endif + case kOOPixMapInvalidFormat: + break; } + +#ifndef NDEBUG + [NSException raise:NSInternalInconsistencyException format:@"Unsupported pixmap format in scaler: %@", OOPixMapFormatName(pixMap.format)]; +#else + abort(); +#endif } OOINLINE void StretchHorizontally(OOPixMap srcPx, OOPixMap dstPx) { - NSCParameterAssert(srcPx.components == dstPx.components); + NSCParameterAssert(srcPx.format == dstPx.format); - switch (srcPx.components) + switch (srcPx.format) { - case 4: + case kOOPixMapRGBA: StretchHorizontally4(srcPx, dstPx); - break; + return; - case 1: + case kOOPixMapGrayscale: StretchHorizontally1(srcPx, dstPx); - break; + return; - case 2: + case kOOPixMapGrayscaleAlpha: StretchHorizontally2(srcPx, dstPx); - break; + return; -#ifndef NDEBUG - default: - [NSException raise:NSInternalInconsistencyException format:@"Invalid texture component count: %u", srcPx.components]; -#else - abort(); -#endif + case kOOPixMapInvalidFormat: + break; } + +#ifndef NDEBUG + [NSException raise:NSInternalInconsistencyException format:@"Unsupported pixmap format in scaler: %@", OOPixMapFormatName(srcPx.format)]; +#else + abort(); +#endif } OOINLINE void SqueezeHorizontally(OOPixMap pixMap, OOPixMapDimension dstHeight) { - switch (pixMap.components) + switch (pixMap.format) { - case 4: + case kOOPixMapRGBA: SqueezeHorizontally4(pixMap, dstHeight); - break; + return; - case 1: + case kOOPixMapGrayscale: SqueezeHorizontally1(pixMap, dstHeight); - break; + return; - case 2: + case kOOPixMapGrayscaleAlpha: SqueezeHorizontally2(pixMap, dstHeight); - break; + return; -#ifndef NDEBUG - default: - [NSException raise:NSInternalInconsistencyException format:@"Invalid texture component count: %u", pixMap.components]; -#else - abort(); -#endif + case kOOPixMapInvalidFormat: + break; } + +#ifndef NDEBUG + [NSException raise:NSInternalInconsistencyException format:@"Unsupported pixmap format in scaler: %@", OOPixMapFormatName(pixMap.format)]; +#else + abort(); +#endif } @@ -258,7 +264,7 @@ OOPixMap OOScalePixMap(OOPixMap srcPx, OOPixMapDimension dstWidth, OOPixMapDimen size_t dstSize = srcPx.rowBytes * dstHeight; if (leaveSpaceForMipMaps && dstWidth <= srcPx.width) dstSize = dstSize * 4 / 3; - dstPx = OOAllocatePixMap(srcPx.width, dstHeight, srcPx.components, 0, dstSize); + dstPx = OOAllocatePixMap(srcPx.width, dstHeight, srcPx.format, 0, dstSize); if (EXPECT_NOT(!OOIsValidPixMap(dstPx))) { OK = NO; goto FAIL; } StretchVertically(srcPx, dstPx); @@ -278,17 +284,17 @@ OOPixMap OOScalePixMap(OOPixMap srcPx, OOPixMapDimension dstWidth, OOPixMapDimen if (srcPx.width < dstWidth) { // Stretch horizontally. This requires a separate buffer. - size_t dstSize = srcPx.components * dstWidth * srcPx.height; + size_t dstSize = OOPixMapBytesPerPixel(srcPx) * dstWidth * srcPx.height; if (leaveSpaceForMipMaps) dstSize = dstSize * 4 / 3; if (dstSize <= sparePx.bufferSize) { - dstPx = OOMakePixMap(sparePx.pixels, dstWidth, srcPx.height, srcPx.components, 0, sparePx.bufferSize); + dstPx = OOMakePixMap(sparePx.pixels, dstWidth, srcPx.height, srcPx.format, 0, sparePx.bufferSize); sparePx = kOONullPixMap; } else { - dstPx = OOAllocatePixMap(dstWidth, srcPx.height, srcPx.components, 0, dstSize); + dstPx = OOAllocatePixMap(dstWidth, srcPx.height, srcPx.format, 0, dstSize); } if (EXPECT_NOT(!OOIsValidPixMap(dstPx))) { OK = NO; goto FAIL; } @@ -302,7 +308,7 @@ OOPixMap OOScalePixMap(OOPixMap srcPx, OOPixMapDimension dstWidth, OOPixMapDimen dstPx = srcPx; dstPx.width = dstWidth; - dstPx.rowBytes = dstPx.width * dstPx.components; + dstPx.rowBytes = dstPx.width * OOPixMapBytesPerPixel(dstPx); DUMP_SCALE_DUMP(dstPx, @"squeezed horizontally"); } else @@ -334,7 +340,7 @@ FAIL: // FIXME: should take an OOPixMap. -BOOL OOGenerateMipMaps(void *textureBytes, OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount planes) +BOOL OOGenerateMipMaps(void *textureBytes, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format) { if (EXPECT_NOT(width != OORoundUpToPowerOf2(width) || height != OORoundUpToPowerOf2(height))) { @@ -347,15 +353,23 @@ BOOL OOGenerateMipMaps(void *textureBytes, OOPixMapDimension width, OOPixMapDime return NO; } - switch (planes) + switch (format) { - case 4: return GenerateMipMaps4(textureBytes, width, height); - case 2: return GenerateMipMaps2(textureBytes, width, height); - case 1: return GenerateMipMaps1(textureBytes, width, height); + case kOOPixMapRGBA: + return GenerateMipMaps4(textureBytes, width, height); + + case kOOPixMapGrayscale: + return GenerateMipMaps1(textureBytes, width, height); + + case kOOPixMapGrayscaleAlpha: + return GenerateMipMaps2(textureBytes, width, height); + + case kOOPixMapInvalidFormat: + break; } - OOLog(kOOLogParameterError, @"%s(): bad plane count (%u, should be 1 or 4) - ignoring, data will be junk.", __FUNCTION__, planes); + OOLog(kOOLogParameterError, @"%s(): bad pixmap format (%@) - ignoring, data will be junk.", __FUNCTION__, OOPixMapFormatName(format)); return NO; } @@ -886,7 +900,7 @@ static void StretchVerticallyN_x1(OOPixMap srcPx, OOPixMap dstPx) src0 = prev = src; - xCount = srcPx.width * srcPx.components; + xCount = srcPx.width * OOPixMapBytesPerPixel(srcPx); for (y = 1; y != dstPx.height; ++y) { @@ -934,7 +948,7 @@ static void StretchVerticallyN_x4(OOPixMap srcPx, OOPixMap dstPx) src0 = prev = (uint32_t *)src; - xCount = (srcPx.width * srcPx.components) >> 2; + xCount = (srcPx.width * OOPixMapBytesPerPixel(srcPx)) >> 2; for (y = 1; y != dstPx.height; ++y) { @@ -984,7 +998,7 @@ static void StretchVerticallyN_x8(OOPixMap srcPx, OOPixMap dstPx) src0 = prev = (uint64_t *)src; - xCount = (srcPx.width * srcPx.components) >> 3; + xCount = (srcPx.width * OOPixMapBytesPerPixel(srcPx)) >> 3; for (y = 1; y != dstPx.height; ++y) { @@ -1027,7 +1041,7 @@ static void StretchHorizontally1(OOPixMap srcPx, OOPixMap dstPx) uint_fast16_t weight0, weight1; uint_fast32_t fractX, deltaX; // X coordinate, fixed-point (20.12), allowing widths up to 1 mebipixel - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 1 && OOIsValidPixMap(dstPx) && dstPx.components == 1); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 1 && OOIsValidPixMap(dstPx) && OOPixMapBytesPerPixel(dstPx) == 1); srcStart = srcPx.pixels; srcRowBytes = srcPx.rowBytes; @@ -1086,7 +1100,7 @@ static void StretchHorizontally2(OOPixMap srcPx, OOPixMap dstPx) uint_fast16_t weight0, weight1; uint_fast32_t fractX, deltaX; // X coordinate, fixed-point (20.12), allowing widths up to 1 mebipixel - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 2 && OOIsValidPixMap(dstPx) && dstPx.components == 2); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 2 && OOIsValidPixMap(dstPx) && OOPixMapBytesPerPixel(dstPx) == 2); srcStart = srcPx.pixels; srcRowBytes = srcPx.rowBytes; @@ -1151,7 +1165,7 @@ static void StretchHorizontally4(OOPixMap srcPx, OOPixMap dstPx) uint_fast16_t weight0, weight1; uint_fast32_t fractX, deltaX; // X coordinate, fixed-point (20.12), allowing widths up to 1 mebipixel - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 4 && OOIsValidPixMap(dstPx) && dstPx.components == 4); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 4 && OOIsValidPixMap(dstPx) && OOPixMapBytesPerPixel(dstPx) == 4); srcStart = srcPx.pixels; srcRowBytes = srcPx.rowBytes; @@ -1216,7 +1230,7 @@ static void SqueezeHorizontally1(OOPixMap srcPx, OOPixMapDimension dstWidth) uint_fast32_t accum, weight; uint_fast8_t borderWeight; - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 1); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 1); srcStart = srcPx.pixels; dst = srcStart; // Output is placed in same buffer, without line padding. @@ -1278,7 +1292,7 @@ static void SqueezeVertically1(OOPixMap srcPx, OOPixMapDimension dstHeight) uint_fast32_t accum, weight; uint_fast8_t startWeight, endWeight; - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 1); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 1); dst = srcPx.pixels; // Output is placed in same buffer, without line padding. srcRowBytes = srcPx.rowBytes; @@ -1366,7 +1380,7 @@ static void SqueezeHorizontally2(OOPixMap srcPx, OOPixMapDimension dstWidth) uint_fast32_t accumHi, accumLo, weight; uint_fast8_t borderWeight; - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 2); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 2); srcStart = srcPx.pixels; dst = srcStart; // Output is placed in same buffer, without line padding. @@ -1427,7 +1441,7 @@ static void SqueezeVertically2(OOPixMap srcPx, OOPixMapDimension dstHeight) uint_fast32_t accumHi, accumLo, weight; uint_fast8_t startWeight, endWeight; - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 2); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 2); dst = srcPx.pixels; // Output is placed in same buffer, without line padding. srcRowBytes = srcPx.rowBytes; @@ -1514,7 +1528,7 @@ static void SqueezeVertically2(OOPixMap srcPx, OOPixMapDimension dstHeight) */ #define ACCUM4TOPX() ( \ (((accum1 / weight) & 0xFF) << 24) | \ - (((accum3 / weight) & 0xFF) << 8) | \ + (((accum3 / weight) & 0xFF) << 8) | \ (((accum2 / weight) & 0xFF) << 16) | \ ((accum4 / weight) & 0xFF) \ ) @@ -1529,7 +1543,7 @@ static void SqueezeHorizontally4(OOPixMap srcPx, OOPixMapDimension dstWidth) uint_fast32_t accum1, accum2, accum3, accum4, weight; uint_fast8_t borderWeight; - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 4); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 4); srcStart = srcPx.pixels; dst = srcStart; // Output is placed in same buffer, without line padding. @@ -1591,7 +1605,7 @@ static void SqueezeVertically4(OOPixMap srcPx, OOPixMapDimension dstHeight) uint_fast32_t accum1, accum2, accum3, accum4, weight; uint_fast8_t startWeight, endWeight; - NSCParameterAssert(OOIsValidPixMap(srcPx) && srcPx.components == 4); + NSCParameterAssert(OOIsValidPixMap(srcPx) && OOPixMapBytesPerPixel(srcPx) == 4); dst = srcPx.pixels; // Output is placed in same buffer, without line padding. srcRowBytes = srcPx.rowBytes;