initial commit

This commit is contained in:
2026-02-12 00:45:31 -08:00
commit 5f168f370b
3024 changed files with 804889 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 77;
objects = {
/* Begin PBXCopyFilesBuildPhase section */
19B604CF2D6F15DA00B971F2 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
19B604D12D6F15DA00B971F2 /* PNG_Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = PNG_Test; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
19B604D32D6F15DA00B971F2 /* PNG_Test */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = PNG_Test;
sourceTree = "<group>";
};
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
19B604CE2D6F15DA00B971F2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
19B604C82D6F15DA00B971F2 = {
isa = PBXGroup;
children = (
19B604D32D6F15DA00B971F2 /* PNG_Test */,
19B604D22D6F15DA00B971F2 /* Products */,
);
sourceTree = "<group>";
};
19B604D22D6F15DA00B971F2 /* Products */ = {
isa = PBXGroup;
children = (
19B604D12D6F15DA00B971F2 /* PNG_Test */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
19B604D02D6F15DA00B971F2 /* PNG_Test */ = {
isa = PBXNativeTarget;
buildConfigurationList = 19B604D82D6F15DA00B971F2 /* Build configuration list for PBXNativeTarget "PNG_Test" */;
buildPhases = (
19B604CD2D6F15DA00B971F2 /* Sources */,
19B604CE2D6F15DA00B971F2 /* Frameworks */,
19B604CF2D6F15DA00B971F2 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
19B604D32D6F15DA00B971F2 /* PNG_Test */,
);
name = PNG_Test;
packageProductDependencies = (
);
productName = PNG_Test;
productReference = 19B604D12D6F15DA00B971F2 /* PNG_Test */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
19B604C92D6F15DA00B971F2 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastUpgradeCheck = 1620;
TargetAttributes = {
19B604D02D6F15DA00B971F2 = {
CreatedOnToolsVersion = 16.2;
};
};
};
buildConfigurationList = 19B604CC2D6F15DA00B971F2 /* Build configuration list for PBXProject "PNG_Test" */;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 19B604C82D6F15DA00B971F2;
minimizedProjectReferenceProxies = 1;
preferredProjectObjectVersion = 77;
productRefGroup = 19B604D22D6F15DA00B971F2 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
19B604D02D6F15DA00B971F2 /* PNG_Test */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
19B604CD2D6F15DA00B971F2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
19B604D62D6F15DA00B971F2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 15.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
19B604D72D6F15DA00B971F2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 15.2;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
};
name = Release;
};
19B604D92D6F15DA00B971F2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CODE_SIGN_STYLE = Automatic;
GCC_C_LANGUAGE_STANDARD = gnu89;
"OTHER_CFLAGS[arch=*]" = "";
"OTHER_CPLUSPLUSFLAGS[arch=*]" = "";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
19B604DA2D6F15DA00B971F2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CODE_SIGN_STYLE = Automatic;
GCC_C_LANGUAGE_STANDARD = gnu89;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
19B604CC2D6F15DA00B971F2 /* Build configuration list for PBXProject "PNG_Test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
19B604D62D6F15DA00B971F2 /* Debug */,
19B604D72D6F15DA00B971F2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
19B604D82D6F15DA00B971F2 /* Build configuration list for PBXNativeTarget "PNG_Test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
19B604D92D6F15DA00B971F2 /* Debug */,
19B604DA2D6F15DA00B971F2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 19B604C92D6F15DA00B971F2 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>PNG_Test.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,13 @@
CFLAGS=-Wall -O2 -g -fsanitize=address,undefined
LIBS =
all: png_test
png_test: main.o
$(CC) main.o -fsanitize=address,undefined -g $(LIBS) -o png_test
main.o: main.cpp
$(CXX) $(CFLAGS) -c main.cpp
clean:
rm -rf *.o png_test

View File

@@ -0,0 +1,365 @@
//
// main.cpp
// PNG_Test
//
// Created by Laurence Bank on 2/26/25.
//
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#define __LINUX__
#define ZLIB_DEBUG
#define verbose 0
#define INFLATE_STRICT
#include "../../../src/zutil.c"
#include "../../../src/inflate.c"
#include "../../../src/inffast.c"
#include "../../../src/inftrees.c"
#include "../../../src/crc32.c"
#undef DO1
#undef DO8
#include "../../../src/adler32.c"
#include "../../../src/PNGdec.cpp"
#include "../../../test_images/octocat_8bpp.h"
#include "../../../test_images/octocat.h"
#include "../../../test_images/bugpng.h"
PNG png;
int xoff, yoff, iBpp;
int iWidth, iLines;
uint32_t palentry24;
uint16_t palentry16;
uint32_t u32BG;
uint16_t u16Out;
uint8_t ucPixelType;
//
// Return the current time in microseconds
//
int Micros(void)
{
int iTime;
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
iTime = (int)(1000000*res.tv_sec + res.tv_nsec/1000);
return iTime;
} /* Micros() */
//
// Create a private structure to pass info to the draw callback
// For this example we want to pass a random x/y starting point
//
typedef struct my_private_struct
{
int xoff, yoff; // corner offset
} PRIVATE;
// Second draw callback for testing conversion to RGB565
int PNGDraw2(PNGDRAW *pDraw)
{
uint16_t usPixels[320];
png.getLineAsRGB565(pDraw, usPixels, ucPixelType, u32BG);
if (pDraw->y == 0) { // get first pixel of first line for testing
u16Out = usPixels[0];
}
return 1;
} /* PNGDraw2() */
int PNGDraw(PNGDRAW *pDraw)
{
PRIVATE *pPriv = (PRIVATE *)pDraw->pUser;
if (pPriv) {
xoff = pPriv->xoff;
yoff = pPriv->yoff;
}
palentry24 = *(uint32_t *)&pDraw->pPalette[2*3];
palentry24 &= 0xffffff;
if (pDraw->pFastPalette) { // this pointer is only valid when the PNG_FAST_PALETTE option is used
palentry16 = pDraw->pFastPalette[2];
}
iBpp = pDraw->iBpp;
iWidth = pDraw->iWidth;
iLines++;
return 1;
} /* PNGDraw() */
int PNGDraw3(PNGDRAW *pDraw)
{
return 0; // abort the decode immediately
}
//
// Simple logging print
//
void PNGLOG(int line, char *string, const char *result)
{
printf("Line: %d: msg: %s%s\n", line, string, result);
} /* PNGLOG() */
int main(int argc, const char * argv[]) {
int i, rc, w, h, iTotal, iTime1, iTime2;
uint8_t *pFuzzData;
char *szTestName;
int iTotalPass, iTotalFail;
uint8_t *pFrameBuffer, c1, c2;
uint32_t pal1;
uint16_t pal2;
PRIVATE priv;
const char *szStart = " - START";
iTotalPass = iTotalFail = iTotal = 0;
// Test 0 - Correct file read continuation
iTotal++;
szTestName = (char *)"Test Continuation";
PNGLOG(__LINE__, szTestName, szStart);
rc = png.openFLASH((uint8_t *)bugpng, sizeof(bugpng), PNGDraw);
if (rc == PNG_SUCCESS) {
w = png.getWidth();
h = png.getHeight();
priv.xoff = w/2; // arbitrary values to see if they get passed properly
priv.yoff = h/2;
xoff = yoff = 0;
rc = png.decode(&priv, 0);
if (rc == PNG_SUCCESS) {
if (xoff == priv.xoff && yoff == priv.yoff) {
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
} else {
PNGLOG(__LINE__, szTestName, "Error decoding");
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
} else {
PNGLOG(__LINE__, szTestName, "Error opening PNG file.");
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 1 - Test User pointer";
iTotal++;
szTestName = (char *)"Test User pointer";
PNGLOG(__LINE__, szTestName, szStart);
rc = png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw);
if (rc == PNG_SUCCESS) {
w = png.getWidth();
h = png.getHeight();
priv.xoff = w/2; // arbitrary values to see if they get passed properly
priv.yoff = h/2;
xoff = yoff = 0;
rc = png.decode(&priv, 0);
if (xoff == priv.xoff && yoff == priv.yoff) {
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
} else {
PNGLOG(__LINE__, szTestName, "Error opening PNG file.");
}
// Test 2 - Verify bad parameters return an error
szTestName = (char *)"PNG bad parameter test 1";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), NULL);
// no PNGDraw callback and no framebuffer = invalid
png.decode(NULL, 0);
if (png.getLastError() == PNG_NO_BUFFER) {
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 3 - Verify pixel format
szTestName = (char *)"PNG verify pixel format";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw);
iBpp = 0;
png.decode(NULL, 0);
if (iBpp == 8) { // should be 8 bits per pixel
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 4 - Verify correct dimensions
szTestName = (char *)"PNG verify correct dimensions";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw);
iWidth = iLines = 0;
png.decode(NULL, 0);
if (iWidth == 120 && iLines == 100) { // should be 4 bits per pixel
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 5 - Check CRC option
szTestName = (char *)"PNG Check CRC timing";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw);
iTime1 = Micros();
png.decode(NULL, 0); // without CRC check should be faster
iTime1 = Micros() - iTime1;
png.close();
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw);
iTime2 = Micros();
png.decode(NULL, PNG_CHECK_CRC); // with CRC check should be slower
iTime2 = Micros() - iTime2;
png.close();
if (iTime1 < iTime2) { // skipping CRC check should be faster
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 6 - Check palette options
szTestName = (char *)"PNG Check palette options";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw);
png.decode(NULL, 0); // default palette has 24-bit entries
pal1 = palentry24;
png.close();
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw);
png.decode(NULL, PNG_FAST_PALETTE); // Fast palette is RGB565 little-endian
pal2 = palentry16;
png.close();
if (pal1 == 0x2c2c2a && pal2 == 0x2965) { // correct 24-bit and 16-bit palette values
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 7 - Check full framebuffer decode
szTestName = (char *)"PNG Check full framebuffer decode";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), NULL);
pFrameBuffer = (uint8_t *)malloc(png.getWidth() * png.getHeight()); // just big enough for 8-bpp pixels
png.setBuffer(pFrameBuffer);
png.decode(NULL, 0);
png.close();
c1 = pFrameBuffer[60 + (10 * 120)]; // pixel at (60,10)
c2 = pFrameBuffer[40 + (40 * 120)]; // pixel at (40,40)
if ( c1 == 2 && c2 == 15) { // check a pixel from first line and 50th line for correct colors
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
free(pFrameBuffer);
// Test 8 - check 8-bit to RGB565 conversion and alpha blending
ucPixelType = PNG_RGB565_BIG_ENDIAN;
u32BG = 0x00ff00; // set background color to pure green
szTestName = (char *)"PNG Verify 8-bit to RGB565 output";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
u16Out = 0xffff;
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw2);
png.setBuffer(NULL);
png.decode(NULL, 0);
png.close();
if (u16Out == 0xe007) { // check transparnet pixel (0,0) to see if it matches the 32-bit BG color we asked for
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 9 - check 32-bit to RGB565 conversion and alpha blending
ucPixelType = PNG_RGB565_BIG_ENDIAN;
u32BG = 0xff0000; // set background color to pure blue
szTestName = (char *)"PNG Verify 32-bit to RGB565 output";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
u16Out = 0xffff;
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw2);
png.setBuffer(NULL);
png.decode(NULL, 0);
png.close();
if (u16Out == 0x1f00) { // check transparnet pixel (0,0) to see if it matches the 32-bit BG color we asked for
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// Test 10 - check the decoding can be aborted when the PNGDraw callback returns 0
ucPixelType = PNG_RGB565_BIG_ENDIAN;
szTestName = (char *)"PNG decode aborted early";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
u16Out = 0xffff;
png.openFLASH((uint8_t *)octocat_8bpp, sizeof(octocat_8bpp), PNGDraw3);
png.setBuffer(NULL);
rc = png.decode(NULL, 0);
png.close();
if (rc == PNG_QUIT_EARLY) { // check transparnet pixel (0,0) to see if it matches the 32-bit BG color we asked for
iTotalPass++;
PNGLOG(__LINE__, szTestName, " - PASSED");
} else {
iTotalFail++;
PNGLOG(__LINE__, szTestName, " - FAILED");
}
// FUZZ testing
// Randomize the input data (file header and compressed data) and confirm that the library returns an error code
// and doesn't have an invalid pointer exception
printf("Begin fuzz testing...\n");
szTestName = (char *)"Single Byte Sequential Corruption Test";
iTotal++;
pFuzzData = (uint8_t *)malloc(sizeof(octocat_8bpp));
PNGLOG(__LINE__, szTestName, szStart);
// We don't need to corrupt the file all the way to the end because it will take a loooong time
// The header is the main area where corruption can cause erratic behavior
for (i=0; i<sizeof(octocat_8bpp); i++) { // corrupt each byte one at a time by inverting it
memcpy(pFuzzData, octocat_8bpp, sizeof(octocat_8bpp)); // start with the valid data
pFuzzData[i] = ~pFuzzData[i]; // invert the bits of this byte
if (png.openFLASH(pFuzzData, sizeof(octocat_8bpp), PNGDraw) == PNG_SUCCESS) { // the PNG header may be rejected
png.decode(NULL, 0);
}
} // for each test
PNGLOG(__LINE__, szTestName, " - PASSED");
iTotalPass++;
// Fuzz test part 2 - multi-byte random corruption
szTestName = (char *)"Multi-Byte Random Corruption Test";
iTotal++;
PNGLOG(__LINE__, szTestName, szStart);
for (i=0; i<1000; i++) { // 1000 iterations of random spots in the file to corrupt with random values
int iOffset;
memcpy(pFuzzData, octocat_8bpp, sizeof(octocat_8bpp)); // start with the valid data
iOffset = rand() % sizeof(octocat_8bpp);
pFuzzData[iOffset] = (uint8_t)rand();
iOffset = rand() % sizeof(octocat_8bpp); // corrupt 2 spots just for good measure
pFuzzData[iOffset] = (uint8_t)rand();
if (png.openFLASH(pFuzzData, sizeof(octocat_8bpp), PNGDraw) == PNG_SUCCESS) { // the PNG header may be rejected
png.decode(NULL, 0);
}
} // for each test
PNGLOG(__LINE__, szTestName, " - PASSED");
iTotalPass++;
free(pFuzzData);
printf("Total tests: %d, %d passed, %d failed\n", iTotal, iTotalPass, iTotalFail);
return 0;
} /* main() */