Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/isaacl/ColourSpace
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local me = { } local bc = require('Module:BaseConvert') local Tuple = require('Module:Sandbox/isaacl/ColourSpace/Tuple') local Formats = require('Module:Sandbox/isaacl/ColourSpace/Formats') local infoFor = { sRGB = { colourSpace = 'sRGB', formatType = 'float', defaultConversion = 'sRGB24bit', parseInput = function(args) local digitPattern = '^([%.%d]+)%%?$' local red = string.match(args[1], digitPattern) local green = string.match(args[2], digitPattern) local blue = string.match(args[3], digitPattern) return { red, green, blue } end, isInputFormat = function(args) local sRGBPattern = '^[%.%d]+%%$' if ( args[3] ~= nil and string.match(args[1], sRGBPattern) and string.match(args[2], sRGBPattern) and string.match(args[3], sRGBPattern) ) then return true end return false end, -- end of isInputFormat function display = function(self, separator) local red = self[1] .. '%' local green = self[2] .. '%' local blue = self [3] .. '%' return Tuple.display({ red, green, blue }, separator) end, mapParametersFrom = { sRGB24bit = function( colourValue ) local red = colourValue[1] / 255 * 100 local green = colourValue[2] / 255 * 100 local blue = colourValue[3] / 255 * 100 return { red, green, blue } end, }, -- end of mapping functions }, -- info for sRGB sRGB24bit = { colourSpace = 'sRGB', formatType = '24bit', defaultConversion = 'sRGB', isInputFormat = function(args) local digitPattern = '^%d+$' if ( args[3] ~= nil and string.match(args[1], digitPattern) and string.match(args[2], digitPattern) and string.match(args[3], digitPattern) -- for some reason, tonumber() is required for range checking to work and (tonumber(args[1]) <= 255) and (tonumber(args[2]) <= 255) and (tonumber(args[3]) <= 255) ) then return true end return false end, display = function(self, separator) return Tuple.display(self, separator) end, mapParametersFrom = { sRGB = function(colourValue) local red = math.floor(colourValue[1] * 255 / 100 + 0.5) local green = math.floor(colourValue[2] * 255 / 100 + 0.5) local blue = math.floor(colourValue[3] * 255 / 100 + 0.5) return { red, green, blue } end, sRGB24bitHexString = function(colourValue) return colourValue end, }, -- end of mapping functions }, -- info for sRGB24bit sRGB24bitHexString = { colourSpace = 'sRGB', formatType = '24bit', defaultConversion = 'sRGB24bit', parseInput = function(args) local red local green local blue local hexString = args[1] local hexCharPattern = '^#?(%x%x)(%x%x)(%x%x)$' local fDoubleChar = false if ( #hexString == 3 or #hexString == 4 ) then hexCharPattern = '^#?(%x)(%x)(%x)$' fDoubleChar = true end red, green, blue = string.match(hexString, hexCharPattern) if ( fDoubleChar ) then red = red .. red; green = green .. green; blue = blue .. blue; end red = bc.convert({n = red, base = 10, from = 16}) green = bc.convert({n = green, base = 10, from = 16}) blue = bc.convert({n = blue, base = 10, from = 16}) return { red, green, blue } end, isInputFormat = function(args) if ( string.match(args[1], '^#%x%x%x$') or string.match(args[1], '^#%x%x%x%x%x%x$' ) ) then return true end return false end, display = function(self, separator) local red = string.format('#%02X', self[1]) local green = string.format('%02X', self[2]) local blue = string.format('%02X', self[3]) return Tuple.display({ red, green, blue }, '') end, mapParametersFrom = { sRGB24bit = function( colourValue ) return colourValue end, }, -- end of mapping functions }, -- info for sRGB24bitHexString } -- data for formats function me.buildColourTuple(args, parameters) local result = Tuple.clone(args) result.format = parameters.format result.colourSpace = parameters.colourSpace result.defaultConversion = parameters.defaultConversion result.fValid = true result.display = function(self, separator) return parameters.displayFunc(self, separator) end return result end -- function buildColourTuple local options = { separator = ', ', displayPrefix = '', displaySuffix = '', } local formatTypeFor = { } local checkInputFormatFor = { } me.create = { } local createFromParsedInput = { } me.mapTo = { } local colourSpaceFor = { } local commonFormatForColourSpace = { sRGB = { andFormatType = { float = 'sRGB', ['24bit'] = 'sRGB24bit', }, }, } local function createInvalidColourValue(errorMsg) local invalidColourValue = { -1, -1, -1, fValid = false, errorMessage = errorMsg, display = function(self, separator) return 'InvalidValue ' .. self.errorMessage end, } return invalidColourValue end me.configureFormatInfo = function(infoFor) for format, info in pairs(infoFor) do -- If basic information for the format has not been defined -- already, configure it if ( me.create[format] == nil ) then createFromParsedInput[format] = function(parsedArgs) return me.buildColourTuple(parsedArgs, { format = format, colourSpace = info.colourSpace, defaultConversion = info.defaultConversion, displayFunc = info.display, }) end -- function createFromParsedInput[format] me.create[format] = function (args) local parsedArgs if ( info.parseInput ~= nil ) then parsedArgs = info.parseInput(args) else parsedArgs = args end if ( parsedArgs == nil ) then return createInvalidColourValue('badInputValues') end return createFromParsedInput[format](parsedArgs) end -- function me.create[format] formatTypeFor[format] = info.formatType colourSpaceFor[format] = info.colourSpace if ( info.isInputFormat ~= nil ) then checkInputFormatFor[format] = info.isInputFormat end end -- if me.create[format] == nil, configure basic info for format -- Define mapping functions from other formats to the -- current format being configured. for startFormat, mapper in pairs(info.mapParametersFrom) do if ( me.mapTo[format] == nil ) then me.mapTo[format] = { from = { } } end me.mapTo[format].from[startFormat] = function(parameters) local copy = Tuple.clone(parameters) local mappedParameters = mapper(copy) if ( mappedParameters == nil ) then return createInvalidColourValue('conversionError ' .. parameters:display() ) end return createFromParsedInput[format]( mappedParameters ) end end -- loop over info.mapParametersFrom end -- loop over infoFor table end me.configureFormatInfo(infoFor) for idx=1, #Formats do local formatInfo = require('Module:Sandbox/isaacl/ColourSpace/Formats/' .. Formats[idx]) me.configureFormatInfo(formatInfo.infoFor) end function me.loadFormatInfo(format) -- try to load the required module for the format local formatInfo = require('Module:Sandbox/isaacl/ColourSpace/Formats/' .. format) if ( formatInfo ~= nil ) then me.configureFormatInfo(formatInfo.infoFor) return format end return nil end function me.determineInputFormat(frame) local args = frame.args local fromFormat = frame.args["from"] if (fromFormat ~= nil) then if ( me.create[fromFormat] ~= nil ) then return fromFormat else -- try to load the required module for the format return me.loadFormatInfo(fromFormat) end end for format, isInputFormat in pairs(checkInputFormatFor) do if ( isInputFormat(args) ) then return format end end -- unable to deduce format return nil end -- function determineInputFormat() local function determineOutputFormat(frame, startValue) local toFormat = frame.args["to"] if (toFormat ~= nil) then if ( me.create[toFormat] ~= nil ) then return toFormat else -- try to load the required module for the format return me.loadFormatInfo(toFormat) end end -- use default conversion return startValue.defaultConversion end -- function determineOutputFormat() local function convertBetweenFormats(colourValue, listOfFormats) local convertedValue = colourValue for idx, nextFormat in ipairs(listOfFormats) do if (convertedValue.format ~= nextFormat) then if ( me.mapTo[nextFormat].from[convertedValue.format] == nil ) then return createInvalidColourValue('noConversionAvailable from ' .. convertedValue.format .. ' to ' .. nextFormat) end convertedValue = me.mapTo[nextFormat].from[convertedValue.format](convertedValue) if (not convertedValue.fValid) then -- error in conversion; return immediately with the invalidValue return convertedValue end end end -- loop over list of formats to convert between return convertedValue end -- function convertBetweenFormats function me.convertColour(frame) if ( frame.args[1] == nil ) then return '' end if ( frame.args.separator ~= nil ) then options.separator = frame.args.separator end local startFormat = me.determineInputFormat(frame) if ( startFormat == nil ) then return 'badInputFormat' end local startValue = me.create[startFormat](frame.args) if ( not startValue.fValid ) then return startValue:display() end local endFormat = determineOutputFormat(frame, startValue) if ( endFormat == nil ) then return 'badOutputFormat' end if ( startFormat == endFormat ) then return startValue:display(options.separator) end local result = { } -- If a direct conversion exists, use it if (me.mapTo[endFormat].from[startFormat] ~= nil) then result = me.mapTo[endFormat].from[startFormat](startValue) return result:display(options.separator) end local listOfFormats = { } -- If the start and end formats are in the same colour space: -- first, convert to the common format for the starting colour space and format type -- second, convert to the common format for the ending colour space and format type -- third, convert to the ending format type if (colourSpaceFor[startFormat] == colourSpaceFor[endFormat]) then table.insert(listOfFormats, commonFormatForColourSpace[colourSpaceFor[startFormat]].andFormatType[formatTypeFor[startFormat]] ) table.insert(listOfFormats, commonFormatForColourSpace[colourSpaceFor[endFormat]].andFormatType[formatTypeFor[endFormat]] ) table.insert(listOfFormats, endFormat) result = convertBetweenFormats(startValue, listOfFormats) else -- if the start and end formats are in different colour spaces: -- first, convert to the common format for the starting colour space and format type -- second, convert to the common floating point format for the starting colour space -- third, convert to the common floating point format for the ending colour space -- fourth, convert to the common format for the ending colour space and format type -- fifth, convert to the ending format type table.insert(listOfFormats, commonFormatForColourSpace[colourSpaceFor[startFormat]].andFormatType[formatTypeFor[startFormat]] ) table.insert(listOfFormats, commonFormatForColourSpace[colourSpaceFor[startFormat]].andFormatType.float ) table.insert(listOfFormats, commonFormatForColourSpace[colourSpaceFor[endFormat]].andFormatType.float ) table.insert(listOfFormats, commonFormatForColourSpace[colourSpaceFor[endFormat]].andFormatType[formatTypeFor[endFormat]] ) table.insert(listOfFormats, endFormat) result = convertBetweenFormats(startValue, listOfFormats) end return result:display(options.separator) end -- function convertColour() function me.convertColour_fromTemplate(frame) return me.convertColour(frame:getParent()) end -- function templateConvertColour() return me
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Templates used on this page:
Template:Tlx
(
edit
)
Module:Arguments
(
edit
)
Module:Sandbox/isaacl/ColourSpace/doc
(
edit
)
Module:Template link general
(
edit
)