Skip to content

Commit

Permalink
Merge pull request #262 from evo-lua/encode-tga-function
Browse files Browse the repository at this point in the history
Add EncodeTGA to the image processing API
  • Loading branch information
rdw-software authored Jul 15, 2023
2 parents d291241 + 8ede5a6 commit 273e4a5
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
28 changes: 28 additions & 0 deletions Runtime/API/C_ImageProcessing.lua
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,32 @@ function C_ImageProcessing.EncodeJPG(rgbaPixelArray, imageWidthInPixels, imageHe
return tostring(outputBuffer)
end

function C_ImageProcessing.EncodeTGA(rgbaPixelArray, imageWidthInPixels, imageHeightInPixels)
if type(rgbaPixelArray) == "userdata" then
rgbaPixelArray = tostring(rgbaPixelArray)
end

validateString(rgbaPixelArray, "rgbaPixelArray")
validateNumber(imageWidthInPixels, "imageWidthInPixels")
validateNumber(imageHeightInPixels, "imageHeightInPixels")

local rgbaPixelBuffer = buffer.new(#rgbaPixelArray):put(rgbaPixelArray)

local image = ffi_new("stbi_image_t")
image.width = imageWidthInPixels
image.height = imageHeightInPixels
image.data = rgbaPixelBuffer
image.channels = 4

local requiredBufferSize = stbi.bindings.stbi_get_required_tga_size(image)
local outputBuffer = buffer.new()
local startPointer, reservedBufferSize = outputBuffer:reserve(requiredBufferSize)

local numBytesWritten = stbi.bindings.stbi_encode_tga(image, startPointer, reservedBufferSize)
assert(numBytesWritten > 0, "Failed to encode TGA image (preallocated buffer too small?)")
outputBuffer:commit(numBytesWritten)

return tostring(outputBuffer)
end

return C_ImageProcessing
57 changes: 57 additions & 0 deletions Tests/BDD/imageprocessing-namespace.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ local EXAMPLE_IMAGE_BUFFER = buffer.new():put(EXAMPLE_IMAGE_DATA)
local EXAMPLE_BMP_BYTES = C_FileSystem.ReadFile(path.join("Tests", "Fixtures", "rgba-pixels.bmp"))
local EXAMPLE_PNG_BYTES = C_FileSystem.ReadFile(path.join("Tests", "Fixtures", "rgba-pixels.png"))
local EXAMPLE_JPG_BYTES = C_FileSystem.ReadFile(path.join("Tests", "Fixtures", "rgba-pixels.jpg"))
local EXAMPLE_TGA_BYTES = C_FileSystem.ReadFile(path.join("Tests", "Fixtures", "rgba-pixels.tga"))
local EXAMPLE_BMP_BUFFER = buffer.new():put(EXAMPLE_BMP_BYTES)
local EXAMPLE_PNG_BUFFER = buffer.new():put(EXAMPLE_PNG_BYTES)
local EXAMPLE_JPG_BUFFER = buffer.new():put(EXAMPLE_JPG_BYTES)
local EXAMPLE_TGA_BUFFER = buffer.new():put(EXAMPLE_TGA_BYTES)

describe("C_ImageProcessing", function()
describe("DecodeFileContents", function()
Expand Down Expand Up @@ -93,6 +95,22 @@ describe("C_ImageProcessing", function()
assertEquals(imageHeightInPixels, 2)
end)

it("should be able to decode TGA file contents from a string", function()
local rgbaPixelArray, imageWidthInPixels, imageHeightInPixels =
C_ImageProcessing.DecodeFileContents(EXAMPLE_TGA_BYTES)
assertEquals(rgbaPixelArray, EXAMPLE_IMAGE_DATA)
assertEquals(imageWidthInPixels, 2)
assertEquals(imageHeightInPixels, 2)
end)

it("should be able to decode TGA file contents from a string buffer", function()
local rgbaPixelArray, imageWidthInPixels, imageHeightInPixels =
C_ImageProcessing.DecodeFileContents(EXAMPLE_TGA_BUFFER)
assertEquals(rgbaPixelArray, EXAMPLE_IMAGE_DATA)
assertEquals(imageWidthInPixels, 2)
assertEquals(imageHeightInPixels, 2)
end)

it("should throw if garbage bytes are passed as the file contents", function()
local function attemptToDecodeInvalidFile()
C_ImageProcessing.DecodeFileContents("Not a valid image file")
Expand Down Expand Up @@ -227,4 +245,43 @@ describe("C_ImageProcessing", function()
assertThrows(attemptToEncodeInvalidFile, expectedErrorMessage)
end)
end)

describe("EncodeTGA", function()
it("should be able to encode pixel data given as a string", function()
local bmpFileContents = C_ImageProcessing.EncodeTGA(EXAMPLE_IMAGE_DATA, 2, 2)
assertEquals(bmpFileContents, EXAMPLE_TGA_BYTES)
end)

it("should be able to encode pixel data given as a string buffer", function()
local bmpFileContents = C_ImageProcessing.EncodeTGA(EXAMPLE_IMAGE_BUFFER, 2, 2)
assertEquals(bmpFileContents, EXAMPLE_TGA_BYTES)
end)

it("should throw if a non-string type was passed as the pixel buffer", function()
local function attemptToEncodeInvalidFile()
C_ImageProcessing.EncodeTGA(123, 2, 2)
end
local expectedErrorMessage =
"Expected argument rgbaPixelArray to be a string value, but received a number value instead"
assertThrows(attemptToEncodeInvalidFile, expectedErrorMessage)
end)

it("should throw if a non-number type was passed as the image width", function()
local function attemptToEncodeInvalidFile()
C_ImageProcessing.EncodeTGA(EXAMPLE_IMAGE_DATA, "2", 2)
end
local expectedErrorMessage =
"Expected argument imageWidthInPixels to be a number value, but received a string value instead"
assertThrows(attemptToEncodeInvalidFile, expectedErrorMessage)
end)

it("should throw if a non-number type was passed as the image height", function()
local function attemptToEncodeInvalidFile()
C_ImageProcessing.EncodeTGA(EXAMPLE_IMAGE_DATA, 2, "2")
end
local expectedErrorMessage =
"Expected argument imageHeightInPixels to be a number value, but received a string value instead"
assertThrows(attemptToEncodeInvalidFile, expectedErrorMessage)
end)
end)
end)
Binary file added Tests/Fixtures/rgba-pixels.tga
Binary file not shown.

0 comments on commit 273e4a5

Please sign in to comment.