Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local component = require("component")
- local event = require("event")
- local term = require("term")
- local gpu = component.gpu
- local internet = require("internet")
- local computer = require("computer")
- local unicode = require("unicode")
- local bit32 = require("bit32")
- local function stringUnpack(format, str, pos)
- local function unpackInt(str, pos, size, signed)
- local val = 0
- for i = 0, size - 1 do
- val = val + str:byte(pos + i) * (256 ^ i)
- end
- if signed and val >= 2^(size*8-1) then
- val = val - 2^(size*8)
- end
- return val, pos + size
- end
- if format == "<I4" then
- return unpackInt(str, pos, 4, false)
- elseif format == "<I2" then
- return unpackInt(str, pos, 2, false)
- elseif format == "BBB" then
- return str:byte(pos), str:byte(pos+1), str:byte(pos+2), pos+3
- else
- error("Unsupported format: " .. format)
- end
- end
- local function yieldIfNeeded()
- if computer.uptime() % 0.1 < 0.01 then
- os.sleep(0)
- end
- end
- local function downloadImage(url)
- local maxAttempts = 3
- local attempt = 0
- local data = ""
- while attempt < maxAttempts do
- attempt = attempt + 1
- local response = internet.request(url)
- if response then
- for chunk in response do
- data = data .. chunk
- yieldIfNeeded()
- end
- if data ~= "" then
- return data
- end
- end
- print("Attempt " .. attempt .. " failed. Retrying...")
- os.sleep(2)
- end
- error("Failed to download image after " .. maxAttempts .. " attempts")
- end
- -- Mode 1 specific functions
- local function decodeBMPMode1(imageData)
- local width = stringUnpack("<I4", imageData, 19)
- local height = stringUnpack("<I4", imageData, 23)
- local bitsPerPixel = stringUnpack("<I2", imageData, 29)
- local compression = stringUnpack("<I4", imageData, 31)
- local dataOffset = stringUnpack("<I4", imageData, 11)
- if bitsPerPixel ~= 24 or compression ~= 0 then
- error("Unsupported BMP format. Only 24-bit uncompressed BMPs are supported.")
- end
- local decodedImage = {}
- local rowSize = math.floor((bitsPerPixel * width + 31) / 32) * 4
- local xRatio = width / 160
- local yRatio = height / 50
- for y = 0, 49 do
- for x = 0, 159 do
- local srcX = math.floor(x * xRatio)
- local srcY = math.floor(y * yRatio)
- local rowStart = dataOffset + (height - 1 - srcY) * rowSize
- local pixelStart = rowStart + srcX * 3
- local b, g, r = stringUnpack("BBB", imageData, pixelStart + 1)
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- end
- return decodedImage, 160, 50
- end
- local function decodeTIImageMode1(imageData)
- local width = stringUnpack("<I4", imageData, 5)
- local height = stringUnpack("<I4", imageData, 9)
- local pixelData = imageData:sub(21)
- local decodedImage = {}
- for i = 1, #pixelData, 2 do
- local pixel = stringUnpack("<I2", pixelData, i)
- local r = bit32.rshift(bit32.band(pixel, 0x7C00), 10) * 8
- local g = bit32.rshift(bit32.band(pixel, 0x03E0), 5) * 8
- local b = bit32.band(pixel, 0x001F) * 8
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- return decodedImage, width, height
- end
- local function decodeImageMode1(imageData)
- if not imageData or imageData == "" then
- error("No image data received")
- end
- local format = imageData:sub(1, 2)
- if format == "BM" then
- return decodeBMPMode1(imageData)
- elseif format == "TI" then
- return decodeTIImageMode1(imageData)
- else
- error("Unsupported image format")
- end
- end
- local function packColor(r, g, b)
- return (r * 256 + g) * 256 + b
- end
- local function displayImageMode1(decodedImage, x, y, width, height)
- for i = 1, #decodedImage do
- local pixel = decodedImage[i]
- local px = (i - 1) % width + x
- local py = math.floor((i - 1) / width) + y
- local color = packColor(pixel[1], pixel[2], pixel[3])
- gpu.setBackground(color)
- gpu.set(px, py, " ")
- yieldIfNeeded()
- end
- end
- -- Mode 2 specific functions
- local function decodeBMPMode2(imageData)
- local width = stringUnpack("<I4", imageData, 19)
- local height = stringUnpack("<I4", imageData, 23)
- local bitsPerPixel = stringUnpack("<I2", imageData, 29)
- local compression = stringUnpack("<I4", imageData, 31)
- local dataOffset = stringUnpack("<I4", imageData, 11)
- if bitsPerPixel ~= 24 or compression ~= 0 then
- error("Unsupported BMP format. Only 24-bit uncompressed BMPs are supported.")
- end
- local screenWidth, screenHeight = gpu.getResolution()
- local targetWidth = screenWidth * 2
- local targetHeight = screenHeight * 4
- local decodedImage = {}
- local rowSize = math.floor((bitsPerPixel * width + 31) / 32) * 4
- local xRatio = width / targetWidth
- local yRatio = height / targetHeight
- for y = 0, targetHeight - 1 do
- for x = 0, targetWidth - 1 do
- local srcX = math.floor(x * xRatio)
- local srcY = math.floor(y * yRatio)
- local rowStart = dataOffset + (height - 1 - srcY) * rowSize
- local pixelStart = rowStart + srcX * 3
- local b, g, r = stringUnpack("BBB", imageData, pixelStart + 1)
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- end
- return decodedImage, targetWidth, targetHeight
- end
- local function getBrailleCharacter(pixels)
- local brailleBase = 0x2800
- local pattern = 0
- local dotWeights = {1, 2, 4, 8, 16, 32, 64, 128}
- local function adjustBrightness(brightness)
- return math.pow(brightness / 255, 0.5) * 255
- end
- local thresholds = {}
- for i = 1, 8 do
- local brightness = (pixels[i][1] + pixels[i][2] + pixels[i][3]) / 3
- thresholds[i] = adjustBrightness(brightness)
- end
- local avgThreshold = 0
- for i = 1, 8 do
- avgThreshold = avgThreshold + thresholds[i]
- end
- avgThreshold = avgThreshold / 8
- for i = 1, 8 do
- if thresholds[i] > avgThreshold then
- pattern = pattern + dotWeights[i]
- end
- end
- return unicode.char(brailleBase + pattern)
- end
- local function rgbToColor(r, g, b)
- return (r * 65536) + (g * 256) + b
- end
- local function averageColor(colors)
- local r, g, b, count = 0, 0, 0, #colors
- for _, color in ipairs(colors) do
- r = r + color[1]
- g = g + color[2]
- b = b + color[3]
- end
- if count > 0 then
- return {math.floor(r / count), math.floor(g / count), math.floor(b / count)}
- else
- return {0, 0, 0}
- end
- end
- local function blendColors(c1, c2, factor)
- return {
- math.floor(c1[1] * (1 - factor) + c2[1] * factor),
- math.floor(c1[2] * (1 - factor) + c2[2] * factor),
- math.floor(c1[3] * (1 - factor) + c2[3] * factor)
- }
- end
- local function displayImageMode2(decodedImage, x, y, width, height)
- for py = 0, height / 4 - 1 do
- for px = 0, width / 2 - 1 do
- local pixels = {}
- local colors = {}
- for dy = 0, 3 do
- for dx = 0, 1 do
- local ix = px * 2 + dx
- local iy = py * 4 + dy
- local index = iy * width + ix + 1
- local pixel = decodedImage[index]
- pixels[dy * 2 + dx + 1] = pixel
- table.insert(colors, pixel)
- end
- end
- local char = getBrailleCharacter(pixels)
- local fgColor = averageColor(colors)
- local darkestColor = colors[1]
- for i = 2, #colors do
- if colors[i][1] + colors[i][2] + colors[i][3] < darkestColor[1] + darkestColor[2] + darkestColor[3] then
- darkestColor = colors[i]
- end
- end
- local avgColor = averageColor(colors)
- local bgColor = blendColors(darkestColor, avgColor, 0.3)
- gpu.setForeground(rgbToColor(fgColor[1], fgColor[2], fgColor[3]))
- gpu.setBackground(rgbToColor(bgColor[1], bgColor[2], bgColor[3]))
- gpu.set(x + px, y + py, char)
- end
- yieldIfNeeded()
- end
- end
- -- Mode 3 specific functions
- local function decodeBMPMode3(imageData)
- local width = stringUnpack("<I4", imageData, 19)
- local height = stringUnpack("<I4", imageData, 23)
- local bitsPerPixel = stringUnpack("<I2", imageData, 29)
- local compression = stringUnpack("<I4", imageData, 31)
- local dataOffset = stringUnpack("<I4", imageData, 11)
- if bitsPerPixel ~= 24 or compression ~= 0 then
- error("Unsupported BMP format. Only 24-bit uncompressed BMPs are supported.")
- end
- local screenWidth, screenHeight = gpu.getResolution()
- local targetWidth = screenWidth * 2
- local targetHeight = screenHeight * 4
- local decodedImage = {}
- local rowSize = math.floor((bitsPerPixel * width + 31) / 32) * 4
- local xRatio = width / targetWidth
- local yRatio = height / targetHeight
- for y = 0, targetHeight - 1 do
- for x = 0, targetWidth - 1 do
- local srcX = math.floor(x * xRatio)
- local srcY = math.floor(y * yRatio)
- local rowStart = dataOffset + (height - 1 - srcY) * rowSize
- local pixelStart = rowStart + srcX * 3
- local b, g, r = stringUnpack("BBB", imageData, pixelStart + 1)
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- end
- return decodedImage, targetWidth, targetHeight
- end
- local function getBrailleCharacter(pixels)
- local brailleBase = 0x2800
- local pattern = 0
- local dotWeights = {1, 2, 4, 8, 16, 32, 64, 128}
- local function adjustBrightness(brightness)
- return math.pow(brightness / 255, 0.5) * 255
- end
- local thresholds = {}
- for i = 1, 8 do
- local brightness = (pixels[i][1] + pixels[i][2] + pixels[i][3]) / 3
- thresholds[i] = adjustBrightness(brightness)
- end
- local avgThreshold = 0
- for i = 1, 8 do
- avgThreshold = avgThreshold + thresholds[i]
- end
- avgThreshold = avgThreshold / 8
- for i = 1, 8 do
- if thresholds[i] > avgThreshold then
- pattern = pattern + dotWeights[i]
- end
- end
- return unicode.char(brailleBase + pattern)
- end
- local function rgbToColor(r, g, b)
- return (r * 65536) + (g * 256) + b
- end
- local function averageColor(colors)
- local r, g, b, count = 0, 0, 0, #colors
- for _, color in ipairs(colors) do
- r = r + color[1]
- g = g + color[2]
- b = b + color[3]
- end
- if count > 0 then
- return {math.floor(r / count), math.floor(g / count), math.floor(b / count)}
- else
- return {0, 0, 0}
- end
- end
- local function displayImageMode3(decodedImage, x, y, width, height)
- for py = 0, height / 4 - 1 do
- for px = 0, width / 2 - 1 do
- local pixels = {}
- local colors = {}
- for dy = 0, 3 do
- for dx = 0, 1 do
- local ix = px * 2 + dx
- local iy = py * 4 + dy
- local index = iy * width + ix + 1
- local pixel = decodedImage[index]
- pixels[dy * 2 + dx + 1] = pixel
- table.insert(colors, pixel)
- end
- end
- local char = getBrailleCharacter(pixels)
- local fgColor = averageColor(colors)
- local bgColor = averageColor({colors[1], colors[8]})
- gpu.setForeground(rgbToColor(fgColor[1], fgColor[2], fgColor[3]))
- gpu.setBackground(rgbToColor(bgColor[1], bgColor[2], bgColor[3]))
- gpu.set(x + px, y + py, char)
- end
- yieldIfNeeded()
- end
- end
- local function decodeBMPMode4(imageData)
- local width = stringUnpack("<I4", imageData, 19)
- local height = stringUnpack("<I4", imageData, 23)
- local bitsPerPixel = stringUnpack("<I2", imageData, 29)
- local compression = stringUnpack("<I4", imageData, 31)
- local dataOffset = stringUnpack("<I4", imageData, 11)
- if bitsPerPixel ~= 24 or compression ~= 0 then
- error("Unsupported BMP format. Only 24-bit uncompressed BMPs are supported.")
- end
- local screenWidth, screenHeight = gpu.getResolution()
- local targetWidth = screenWidth * 2
- local targetHeight = screenHeight * 2
- local decodedImage = {}
- local rowSize = math.floor((bitsPerPixel * width + 31) / 32) * 4
- local xRatio = width / targetWidth
- local yRatio = height / targetHeight
- for y = 0, targetHeight - 1 do
- for x = 0, targetWidth - 1 do
- local srcX = math.floor(x * xRatio)
- local srcY = math.floor(y * yRatio)
- local rowStart = dataOffset + (height - 1 - srcY) * rowSize
- local pixelStart = rowStart + srcX * 3
- local b, g, r = stringUnpack("BBB", imageData, pixelStart + 1)
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- end
- return decodedImage, targetWidth, targetHeight
- end
- local function displayImageMode4(decodedImage, x, y, width, height)
- for py = 0, height / 2 - 1 do
- for px = 0, width / 2 - 1 do
- local index1 = (py * 2) * width + (px * 2) + 1
- local index2 = (py * 2) * width + (px * 2) + 2
- local index3 = (py * 2 + 1) * width + (px * 2) + 1
- local index4 = (py * 2 + 1) * width + (px * 2) + 2
- local pixel1 = decodedImage[index1]
- local pixel2 = decodedImage[index2]
- local pixel3 = decodedImage[index3]
- local pixel4 = decodedImage[index4]
- local fgColor = averageColor({pixel1, pixel3})
- local bgColor = averageColor({pixel2, pixel4})
- gpu.setForeground(rgbToColor(fgColor[1], fgColor[2], fgColor[3]))
- gpu.setBackground(rgbToColor(bgColor[1], bgColor[2], bgColor[3]))
- gpu.set(x + px, y + py, "▀")
- end
- yieldIfNeeded()
- end
- end
- local function decodeBMPMode5(imageData)
- local width = stringUnpack("<I4", imageData, 19)
- local height = stringUnpack("<I4", imageData, 23)
- local bitsPerPixel = stringUnpack("<I2", imageData, 29)
- local compression = stringUnpack("<I4", imageData, 31)
- local dataOffset = stringUnpack("<I4", imageData, 11)
- if bitsPerPixel ~= 24 or compression ~= 0 then
- error("Unsupported BMP format. Only 24-bit uncompressed BMPs are supported.")
- end
- local screenWidth, screenHeight = gpu.getResolution()
- local targetWidth = screenWidth * 2
- local targetHeight = screenHeight * 2
- local decodedImage = {}
- local rowSize = math.floor((bitsPerPixel * width + 31) / 32) * 4
- local xRatio = width / targetWidth
- local yRatio = height / targetHeight
- for y = 0, targetHeight - 1 do
- for x = 0, targetWidth - 1 do
- local srcX = math.floor(x * xRatio)
- local srcY = math.floor(y * yRatio)
- local rowStart = dataOffset + (height - 1 - srcY) * rowSize
- local pixelStart = rowStart + srcX * 3
- local b, g, r = stringUnpack("BBB", imageData, pixelStart + 1)
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- end
- return decodedImage, targetWidth, targetHeight
- end
- local function displayImageMode5(decodedImage, x, y, width, height)
- for py = 0, height / 2 - 1 do
- for px = 0, width / 2 - 1 do
- local index1 = (py * 2) * width + (px * 2) + 1
- local index2 = (py * 2) * width + (px * 2) + 2
- local index3 = (py * 2 + 1) * width + (px * 2) + 1
- local index4 = (py * 2 + 1) * width + (px * 2) + 2
- local pixels = {decodedImage[index1], decodedImage[index2], decodedImage[index3], decodedImage[index4]}
- local avgColor = averageColor(pixels)
- local fgColor = {math.floor(avgColor[1] / 16), math.floor(avgColor[2] / 16), math.floor(avgColor[3] / 16)}
- local bgColor = {math.floor(pixels[4][1] / 16), math.floor(pixels[4][2] / 16), math.floor(pixels[4][3] / 16)}
- gpu.setForeground(rgbToColor(fgColor[1] * 16, fgColor[2] * 16, fgColor[3] * 16))
- gpu.setBackground(rgbToColor(bgColor[1] * 16, bgColor[2] * 16, bgColor[3] * 16))
- gpu.set(x + px, y + py, "▄")
- end
- yieldIfNeeded()
- end
- end
- local function decodeBMPMode6(imageData)
- local width = stringUnpack("<I4", imageData, 19)
- local height = stringUnpack("<I4", imageData, 23)
- local bitsPerPixel = stringUnpack("<I2", imageData, 29)
- local compression = stringUnpack("<I4", imageData, 31)
- local dataOffset = stringUnpack("<I4", imageData, 11)
- if bitsPerPixel ~= 24 or compression ~= 0 then
- error("Unsupported BMP format. Only 24-bit uncompressed BMPs are supported.")
- end
- local targetWidth = 640
- local targetHeight = 200
- local decodedImage = {}
- local rowSize = math.floor((bitsPerPixel * width + 31) / 32) * 4
- local xRatio = width / targetWidth
- local yRatio = height / targetHeight
- for y = 0, targetHeight - 1 do
- for x = 0, targetWidth - 1 do
- local srcX = math.floor(x * xRatio)
- local srcY = math.floor(y * yRatio)
- local rowStart = dataOffset + (height - 1 - srcY) * rowSize
- local pixelStart = rowStart + srcX * 3
- local b, g, r = stringUnpack("BBB", imageData, pixelStart + 1)
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- end
- return decodedImage, targetWidth, targetHeight
- end
- local function getBrailleCharacterMode6(pixels)
- local brailleBase = 0x2800
- local pattern = 0
- local dotWeights = {1, 2, 4, 8, 16, 32, 64, 128}
- local function adjustBrightness(brightness)
- return math.pow(brightness / 255, 0.5) * 255
- end
- local thresholds = {}
- for i = 1, 8 do
- local brightness = (pixels[i][1] + pixels[i][2] + pixels[i][3]) / 3
- thresholds[i] = adjustBrightness(brightness)
- end
- local avgThreshold = 0
- for i = 1, 8 do
- avgThreshold = avgThreshold + thresholds[i]
- end
- avgThreshold = avgThreshold / 8
- for i = 1, 8 do
- if thresholds[i] > avgThreshold then
- pattern = pattern + dotWeights[i]
- end
- end
- return unicode.char(brailleBase + pattern)
- end
- local function getBrailleCharacterMode6(pixels)
- local brailleBase = 0x2800
- local pattern = 0
- local dotWeights = {1, 2, 4, 8}
- local function adjustBrightness(brightness)
- return math.pow(brightness / 255, 0.5) * 255
- end
- local thresholds = {}
- for i = 1, 4 do
- local brightness = (pixels[i][1] + pixels[i][2] + pixels[i][3]) / 3
- thresholds[i] = adjustBrightness(brightness)
- end
- local avgThreshold = 0
- for i = 1, 4 do
- avgThreshold = avgThreshold + thresholds[i]
- end
- avgThreshold = avgThreshold / 4
- for i = 1, 4 do
- if thresholds[i] > avgThreshold then
- pattern = pattern + dotWeights[i]
- end
- end
- return unicode.char(brailleBase + pattern)
- end
- local function displayImageMode6(decodedImage, x, y, width, height)
- for py = 0, 49 do
- for px = 0, 159 do
- local pixels = {}
- for dy = 0, 3 do
- for dx = 0, 1 do
- local ix = px * 4 + dx
- local iy = py * 4 + dy
- local index = iy * width + ix + 1
- table.insert(pixels, decodedImage[index])
- end
- end
- local char = getBrailleCharacterMode6(pixels)
- local fgColor = averageColor({pixels[1], pixels[2], pixels[3], pixels[4]})
- local bgColor = averageColor({pixels[5], pixels[6], pixels[7], pixels[8]})
- gpu.setForeground(rgbToColor(fgColor[1], fgColor[2], fgColor[3]))
- gpu.setBackground(rgbToColor(bgColor[1], bgColor[2], bgColor[3]))
- gpu.set(x + px, y + py, char)
- end
- yieldIfNeeded()
- end
- end
- local function decodeBMPMode7(imageData)
- local width = stringUnpack("<I4", imageData, 19)
- local height = stringUnpack("<I4", imageData, 23)
- local bitsPerPixel = stringUnpack("<I2", imageData, 29)
- local compression = stringUnpack("<I4", imageData, 31)
- local dataOffset = stringUnpack("<I4", imageData, 11)
- if bitsPerPixel ~= 24 or compression ~= 0 then
- error("Unsupported BMP format. Only 24-bit uncompressed BMPs are supported.")
- end
- local targetWidth = 640
- local targetHeight = 400
- local decodedImage = {}
- local rowSize = math.floor((bitsPerPixel * width + 31) / 32) * 4
- local xRatio = width / targetWidth
- local yRatio = height / targetHeight
- for y = 0, targetHeight - 1 do
- for x = 0, targetWidth - 1 do
- local srcX = math.floor(x * xRatio)
- local srcY = math.floor(y * yRatio)
- local rowStart = dataOffset + (height - 1 - srcY) * rowSize
- local pixelStart = rowStart + srcX * 3
- local b, g, r = stringUnpack("BBB", imageData, pixelStart + 1)
- table.insert(decodedImage, {r, g, b})
- yieldIfNeeded()
- end
- end
- return decodedImage, targetWidth, targetHeight
- end
- local function getBrailleCharacterMode7(pixels)
- local brailleBase = 0x2800
- local pattern = 0
- local dotWeights = {1, 2, 4, 8, 16, 32, 64, 128}
- local function adjustBrightness(brightness)
- return math.pow(brightness / 255, 0.7) * 255
- end
- local thresholds = {}
- for i = 1, 8 do
- local brightness = (pixels[i][1] * 0.299 + pixels[i][2] * 0.587 + pixels[i][3] * 0.114)
- thresholds[i] = adjustBrightness(brightness)
- end
- local avgThreshold = 0
- for i = 1, 8 do
- avgThreshold = avgThreshold + thresholds[i]
- end
- avgThreshold = avgThreshold / 8
- for i = 1, 8 do
- if thresholds[i] > avgThreshold then
- pattern = pattern + dotWeights[i]
- end
- end
- return unicode.char(brailleBase + pattern)
- end
- local function rgbToLabMode7(r, g, b)
- r, g, b = r / 255, g / 255, b / 255
- local x = 0.4124564 * r + 0.3575761 * g + 0.1804375 * b
- local y = 0.2126729 * r + 0.7151522 * g + 0.0721750 * b
- local z = 0.0193339 * r + 0.1191920 * g + 0.9503041 * b
- local function f(t)
- if t > 0.008856 then
- return math.pow(t, 1/3)
- else
- return 7.787 * t + 16/116
- end
- end
- x, y, z = f(x / 0.95047), f(y), f(z / 1.08883)
- return 116 * y - 16, 500 * (x - y), 200 * (y - z)
- end
- local function colorDistanceMode7(c1, c2)
- local l1, a1, b1 = rgbToLabMode7(c1[1], c1[2], c1[3])
- local l2, a2, b2 = rgbToLabMode7(c2[1], c2[2], c2[3])
- local dl, da, db = l1 - l2, a1 - a2, b1 - b2
- return math.sqrt(dl * dl + da * da + db * db)
- end
- local function findClosestColorMode7(color, palette)
- local minDistance = math.huge
- local closestColor = palette[1]
- for _, paletteColor in ipairs(palette) do
- local distance = colorDistanceMode7(color, paletteColor)
- if distance < minDistance then
- minDistance = distance
- closestColor = paletteColor
- end
- end
- return closestColor
- end
- local function createDitherPaletteMode7()
- local palette = {}
- for r = 0, 5 do
- for g = 0, 5 do
- for b = 0, 5 do
- table.insert(palette, {r * 51, g * 51, b * 51})
- end
- end
- end
- for i = 0, 15 do
- table.insert(palette, {i * 17, i * 17, i * 17})
- end
- return palette
- end
- local function displayImageMode7(decodedImage, x, y, width, height)
- local ditherPalette = createDitherPaletteMode7()
- local screenWidth, screenHeight = 160, 50 -- Fixed for tier 3 GPU
- local function getDitheredColor(ix, iy)
- local index = iy * width + ix + 1
- local pixel = decodedImage[index] or {0, 0, 0}
- local ditherMatrix = {
- {0, 8, 2, 10},
- {12, 4, 14, 6},
- {3, 11, 1, 9},
- {15, 7, 13, 5}
- }
- local ditherValue = ditherMatrix[iy % 4 + 1][ix % 4 + 1] / 16
- local ditheredColor = {
- math.min(255, pixel[1] + (ditherValue - 0.5) * 32),
- math.min(255, pixel[2] + (ditherValue - 0.5) * 32),
- math.min(255, pixel[3] + (ditherValue - 0.5) * 32)
- }
- return findClosestColorMode7(ditheredColor, ditherPalette)
- end
- for py = 0, screenHeight - 1 do
- for px = 0, screenWidth - 1 do
- local pixels = {}
- local colors = {}
- for dy = 0, 3 do
- for dx = 0, 1 do
- local ix = px * 4 + dx
- local iy = py * 8 + dy
- local index = iy * width + ix + 1
- local pixel = decodedImage[index] or {0, 0, 0} -- Default to black if out of bounds
- pixels[dy * 2 + dx + 1] = pixel
- table.insert(colors, pixel)
- end
- end
- local char = getBrailleCharacterMode7(pixels)
- local avgColor = averageColor(colors)
- local fgColor = findClosestColorMode7(avgColor, ditherPalette)
- local ditheredColor = getDitheredColor(px * 4, py * 8)
- gpu.setForeground(rgbToColor(fgColor[1], fgColor[2], fgColor[3]))
- gpu.setBackground(rgbToColor(ditheredColor[1], ditheredColor[2], ditheredColor[3]))
- gpu.set(x + px, y + py, char)
- end
- yieldIfNeeded()
- end
- end
- local function OC_BMP()
- term.clear()
- print("░█▀█░█▀▀░░░░░█▀▄░█▄█░█▀█")
- print("░█░█░█░░░▄▄▄░█▀▄░█░█░█▀▀")
- print("░▀▀▀░▀▀▀░░░░░▀▀░░▀░▀░▀░░")
- print("\nOC-BMP : An BMP Image Viewer For OpenComputers Coded By nonogamer9! Version 1.4")
- print("\nSelect mode:")
- print("1. Mode 1 (Normal Tier 3 GPU resolution of 160x50 with 256 colors and a color palette of 16 colors)")
- print("2. Mode 2 (Custom resolution of 320x200 with 256 colors and a color palette of 16 colors)")
- print("3. Mode 3 (Custom resolution of 320x200 with full 24-bit color and a color palette of 16 colors)")
- print("4. Mode 4 (Double Tier 3 GPU resolution of 320x100 with 256 colors and a color palette of 16 colors)")
- print("5. Mode 5 (Pseudo-Color Mode 320x100 with 4096 colors and a color palette of 32 colors)")
- print("6. Mode 6 (High-Resolution Mode of 640x200 with 256 colors and a color palette of 16 colors)")
- print("7. Mode 7 (Ultra-High Resolution Mode of 640x400 with 24 bit color and a color palette of 256 colors)")
- local mode = tonumber(io.read())
- if mode ~= 1 and mode ~= 2 and mode ~= 3 and mode ~= 4 and mode ~= 5 and mode ~= 6 and mode ~= 7 then
- print("Invalid mode. Defaulting to mode 1 (160x50)")
- mode = 1
- end
- print("\nEnter image URL:")
- local url = io.read()
- local success, result = pcall(function()
- print("Downloading image...")
- local imageData = downloadImage(url)
- print("Decoding image...")
- local decodedImage, width, height
- if mode == 1 then
- decodedImage, width, height = decodeBMPMode1(imageData)
- elseif mode == 2 then
- decodedImage, width, height = decodeBMPMode2(imageData)
- elseif mode == 3 then
- decodedImage, width, height = decodeBMPMode3(imageData)
- elseif mode == 4 then
- decodedImage, width, height = decodeBMPMode4(imageData)
- elseif mode == 5 then
- decodedImage, width, height = decodeBMPMode5(imageData)
- elseif mode == 6 then
- decodedImage, width, height = decodeBMPMode6(imageData)
- elseif mode == 7 then
- decodedImage, width, height = decodeBMPMode7(imageData)
- end
- print("Displaying image...")
- local screenWidth, screenHeight = gpu.getResolution()
- local xPos, yPos
- if mode == 1 then
- xPos = math.floor((screenWidth - width) / 2)
- yPos = math.floor((screenHeight - height) / 2)
- elseif mode == 2 or mode == 3 then
- xPos = math.floor((screenWidth - width / 2) / 2)
- yPos = math.floor((screenHeight - height / 4) / 2)
- elseif mode == 4 or mode == 5 then
- xPos = math.floor((screenWidth - width / 2) / 2)
- yPos = math.floor((screenHeight - height / 2) / 2)
- elseif mode == 6 then
- xPos = math.floor((screenWidth - width / 4) / 2)
- yPos = math.floor((screenHeight - height / 4) / 2)
- elseif mode == 7 then
- xPos = math.floor((screenWidth - 160) / 2)
- yPos = math.floor((screenHeight - 50) / 2)
- end
- if mode == 1 then
- displayImageMode1(decodedImage, xPos, yPos, width, height)
- elseif mode == 2 then
- displayImageMode2(decodedImage, xPos, yPos, width, height)
- elseif mode == 3 then
- displayImageMode3(decodedImage, xPos, yPos, width, height)
- elseif mode == 4 then
- displayImageMode4(decodedImage, xPos, yPos, width, height)
- elseif mode == 5 then
- displayImageMode5(decodedImage, xPos, yPos, width, height)
- elseif mode == 6 then
- displayImageMode6(decodedImage, xPos, yPos, width, height)
- elseif mode == 7 then
- displayImageMode7(decodedImage, xPos, yPos, width, height)
- end
- print("Press any key to exit")
- event.pull("key_down")
- end)
- if not success then
- print("Error: " .. tostring(result))
- print("Press any key to exit")
- event.pull("key_down")
- end
- term.clear()
- end
- OC_BMP()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement