1/* 2 PPImagePixelAlphaPremultiplyTables.m 3 4 Copyright 2013-2018 Josh Freeman 5 http://www.twilightedge.com 6 7 This file is part of PikoPixel for Mac OS X and GNUstep. 8 PikoPixel is a graphical application for drawing & editing pixel-art images. 9 10 PikoPixel is free software: you can redistribute it and/or modify it under 11 the terms of the GNU Affero General Public License as published by the 12 Free Software Foundation, either version 3 of the License, or (at your 13 option) any later version approved for PikoPixel by its copyright holder (or 14 an authorized proxy). 15 16 PikoPixel is distributed in the hope that it will be useful, but WITHOUT ANY 17 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more 19 details. 20 21 You should have received a copy of the GNU Affero General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23*/ 24 25#import "PPImagePixelAlphaPremultiplyTables.h" 26 27 28#define kNumLookupTables (kMaxImagePixelComponentValue+1) 29#define kSizeOfLookupTable ((kMaxImagePixelComponentValue+1) * sizeof(PPImagePixelComponent)) 30 31 32PPImagePixelComponent *gImageAlphaPremultiplyTables[kNumLookupTables], 33 *gImageAlphaUnpremultiplyTables[kNumLookupTables]; 34 35 36static bool SetupImageAlphaPremultiplyTables(void); 37 38 39@implementation NSObject (PPImagePixelAlphaPremultiplyTables) 40 41+ (void) load 42{ 43 SetupImageAlphaPremultiplyTables(); 44} 45 46@end 47 48#pragma mark Private functions 49 50static bool SetupImageAlphaPremultiplyTables(void) 51{ 52 int tablesBufferSize, alphaValue, colorValue; 53 unsigned char *premultiplyTablesBuffer = NULL, *unpremultiplyTablesBuffer = NULL; 54 PPImagePixelComponent *currentTable; 55 56 tablesBufferSize = kNumLookupTables * kSizeOfLookupTable; 57 58 premultiplyTablesBuffer = (unsigned char *) malloc (tablesBufferSize); 59 unpremultiplyTablesBuffer = (unsigned char *) malloc (tablesBufferSize); 60 61 if (!premultiplyTablesBuffer || !unpremultiplyTablesBuffer) 62 { 63 goto ERROR; 64 } 65 66 // alphaValue=[0] tables 67 68 // premultiply 69 70 currentTable = premultiplyTablesBuffer; 71 premultiplyTablesBuffer += kSizeOfLookupTable; 72 73 memset(currentTable, 0, kSizeOfLookupTable); 74 gImageAlphaPremultiplyTables[0] = currentTable; 75 76 // unpremultiply 77 78 currentTable = unpremultiplyTablesBuffer; 79 unpremultiplyTablesBuffer += kSizeOfLookupTable; 80 81 memset(currentTable, 0, kSizeOfLookupTable); 82 gImageAlphaUnpremultiplyTables[0] = currentTable; 83 84 85 // alphaValue=[1..MAX] tables 86 87 for (alphaValue=1; alphaValue<=kMaxImagePixelComponentValue; alphaValue++) 88 { 89 // premultiply 90 91 currentTable = premultiplyTablesBuffer; 92 premultiplyTablesBuffer += kSizeOfLookupTable; 93 94 currentTable[0] = 0; 95 96 for (colorValue=1; colorValue<=kMaxImagePixelComponentValue; colorValue++) 97 { 98 currentTable[colorValue] = 99 (PPImagePixelComponent) roundf(((float) colorValue) 100 * ((float) alphaValue) 101 / ((float) kMaxImagePixelComponentValue)); 102 } 103 104 gImageAlphaPremultiplyTables[alphaValue] = currentTable; 105 106 // unpremultiply 107 108 currentTable = unpremultiplyTablesBuffer; 109 unpremultiplyTablesBuffer += kSizeOfLookupTable; 110 111 currentTable[0] = 0; 112 113 for (colorValue=1; colorValue<alphaValue; colorValue++) 114 { 115 currentTable[colorValue] = 116 (PPImagePixelComponent) roundf(((float) colorValue) 117 * ((float) kMaxImagePixelComponentValue) 118 / ((float) alphaValue)); 119 } 120 121 while (colorValue <= kMaxImagePixelComponentValue) 122 { 123 currentTable[colorValue] = kMaxImagePixelComponentValue; 124 colorValue++; 125 } 126 127 gImageAlphaUnpremultiplyTables[alphaValue] = currentTable; 128 } 129 130 return YES; 131 132ERROR: 133 if (premultiplyTablesBuffer) 134 { 135 free(premultiplyTablesBuffer); 136 } 137 138 if (unpremultiplyTablesBuffer) 139 { 140 free(unpremultiplyTablesBuffer); 141 } 142 143 return NO; 144} 145