why does this function only work properly when i supply characters beyond the nornal ascii range?
// Unpack the parameters because fucking excel VBA doesn’t like more than 5 argument
const uint32_t width = width_height_bpp[0];
const uint32_t height = width_height_bpp[1];
const uint32_t bits_per_pixel = width_height_bpp[2];
const uint32_t charsPerCell = width_height_bpp[3];
// This is the number of Excel COLUMNS that will be occupied.
// For example, if the original bitmap width is 512 and charPerCells is 16
// then packedWidth is 32
const uint32_t packedWidth = width / charsPerCell; // Should be 32
// Use std::vector for unpacked pixel data
std::vector<int> bitmap(width * height);
// Use std::vector for unpacked pixel data
std::vector<int> indexmap(width * height);
ProcessImageData(base64BitMap, bitmap.data(), width, height, bits_per_pixel);
ProcessImageData(base64IndexMap, indexmap.data(), width, height, bits_per_pixel);
#if defined(_WIN32) || defined(_WIN64)
// Assuming characterMatrix is a VARIANT containing a 2D SAFEARRAY
SAFEARRAY* characterMap = V_ARRAY(&characterMatrix);
LONG ubound1, lbound1, ubound2, lbound2;
SafeArrayGetUBound(characterMap, 1, &ubound1);
SafeArrayGetLBound(characterMap, 1, &lbound1);
SafeArrayGetUBound(characterMap, 2, &ubound2);
SafeArrayGetLBound(characterMap, 2, &lbound2);
size_t rows = ubound1 - lbound1 + 1;
size_t columns = ubound2 - lbound2 + 1;
if (rows < 1 || columns < 1) return; // Check for valid character map
// Define the bounds for the 2D array (ASCII art)
sab[0].lLbound = 0; sab[0].cElements = height;
sab[1].lLbound = 0; sab[1].cElements = width;
// Create the SAFEARRAY for the ASCII art
SAFEARRAY* asciiArt = SafeArrayCreate(VT_VARIANT, 2, sab);
#else
// Mac-specific code using MinXL
// Convert characterMapVariant to mxl::Arraymxl::Variant
mxl::Arraymxl::Variant characterMap = characterMatrix;
// Assuming the character map is a 2D array with meaningful rows and arbitrary columns
size_t rows = characterMap.Rows();
size_t columns = characterMap.Columns(); // Assuming we need to handle multiple columns now
// USING INTERNAL CHARACTER MAP
// constexpr size_t rows = sizeof(blockElements) / sizeof(blockElements[0]);
// constexpr size_t columns = sizeof(blockElements[0]) / sizeof(char16_t);
if (rows < 1 || columns < 1) return; // Check for valid character map
// Create a 2D mxl::Variant array to hold the ASCII art
mxl::Array<mxl::Variant> asciiArt(height, packedWidth); // Note the dimensions
#endif
// char16_t corresponds to UTF16
// we make it one element larger, to add null-terminating character
std::vector<char16_t> packedChars(charsPerCell + 1);
for (uint32_t y = 0; y < height; ++y)
for (uint32_t packedX = 0; packedX < packedWidth; ++packedX)
//for (uint32_t x = 0; x < width; ++x) {
// Reset the vector for each cell
std::vector<char16_t> packedChars(charsPerCell + 1, L'\0'); // Ensure it's zero-initialized
// Instead of directly placing content on the cell, we iterate further on a character-by-character manner
// This way we pack more than one pixel values per call
for (int charIndex = 0; charIndex < charsPerCell; ++charIndex)
// X is now a more complex index.
uint32_t x = packedX * charsPerCell + charIndex;
int pixelIndex = x * height + y; // Correcting index calculation
// These are the same as before
//--------------------------------
// This is the luminance value of the original bitmap
int pixelValue = bitmap[pixelIndex];
// This is the index of the character map to use for this pixel
int indexValue = indexmap[pixelIndex];
// The PIXEL VALUE is remapped to the vertical dimension of the character matrix
size_t rowIndex = std::min(size_t(pixelValue * (rows - 1) / 255), rows - 1);
// The INDEX VALUE is remapped to the horizontal dimension of the character matrix
size_t colIndex = std::min(size_t(indexValue * (columns - 1) / 255), columns - 1);
#if defined(PLATFORM_WINDOWS)
VARIANT vWord;
VariantInit(&vWord);
// Fetch the string as before
LONG indices[] = { static_cast<LONG>(rowIndex + lbound1), static_cast<LONG>(colIndex + lbound2) };
SafeArrayGetElement(characterMap, indices, &vWord);
// Now, ensure we have a BSTR to work with
if (vWord.vt == VT_BSTR && vWord.bstrVal != nullptr) {
// Directly access the first character of the BSTR
packedChars[charIndex] = vWord.bstrVal[0];
#else
auto vword =characterMap(rowIndex, colIndex);
if (vword.IsString())
{
// We convert the Variant to a mxl::String and get its char16_t buffer
// We only pick the first character in this mode
packedChars[charIndex] = static_castmxl::String(vword).Buffer()[0];
}
// packedChars[charIndex] = blockElements[rowIndex][colIndex];
#endif
}
// We null terminate the strign
packedChars[charsPerCell] = L'\0';
#if defined(PLATFORM_WINDOWS)
// Convert the packed UTF-16 string back into a BSTR for assignment
BSTR bstrResult = SysAllocStringLen(reinterpret_cast<const OLECHAR *>(packedChars.data()), charsPerCell);
// Now, we insert this BSTR into the asciiArt SAFEARRAY
VariantInit(&vPackedWord);
vPackedWord.vt = VT_BSTR;
vPackedWord.bstrVal = bstrResult;
LONG placeIndices[2] = {static_cast<LONG>(y), static_cast<LONG>(packedX)}; // Specify the indices where the BSTR should be placed in the 2D SAFEARRAY
HRESULT hr = SafeArrayPutElement(asciiArt, placeIndices, &vPackedWord);
// Check HRESULT if needed
VariantClear(&vPackedWord); // This also calls SysFreeString on bstrPacked since it's contained within the VARIANT
#else
// mxl::String word = characterMap(rowIndex,colIndex);
mxl::String word(packedChars.data());
asciiArt(y, packedX) = word;
#endif
}
}
#if defined(PLATFORM_WINDOWS)
// Assign the populated SAFEARRAY to the result VARIANT
VariantClear(&result); // Clear the result VARIANT first
result.vt = VT_ARRAY | VT_VARIANT; // Specify that this is an array of VARIANTs
result.parray = asciiArt;
#else
// Assign the populated 2D array to the result
result = std::move(asciiArt);
#endif