6f1a1a274e
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
291 lines
5.7 KiB
C
291 lines
5.7 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "common.h"
|
|
|
|
static int tests = 0;
|
|
static int failed = 0;
|
|
int assertionFailed = 0;
|
|
int assertionNum = 0;
|
|
static const char *testName = NULL;
|
|
static const char *testFunc = NULL;
|
|
|
|
const char levelChar[4] = {'L', 'M', 'Q', 'H'};
|
|
const char *modeStr[5] = {"nm", "an", "8", "kj", "st"};
|
|
|
|
int ncmpBin(char *correct, BitStream *bstream, size_t len)
|
|
{
|
|
int bit;
|
|
size_t i;
|
|
char *p;
|
|
|
|
if(len != BitStream_size(bstream)) {
|
|
printf("Length is not match: %zu, %zu expected.\n", BitStream_size(bstream), len);
|
|
return -1;
|
|
}
|
|
|
|
p = correct;
|
|
i = 0;
|
|
while(*p != '\0') {
|
|
while(*p == ' ') {
|
|
p++;
|
|
}
|
|
bit = (*p == '1')?1:0;
|
|
if(bstream->data[i] != bit) return -1;
|
|
i++;
|
|
p++;
|
|
if(i == len) break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmpBin(char *correct, BitStream *bstream)
|
|
{
|
|
size_t len = 0;
|
|
char *p;
|
|
|
|
|
|
for(p = correct; *p != '\0'; p++) {
|
|
if(*p != ' ') len++;
|
|
}
|
|
return ncmpBin(correct, bstream, len);
|
|
}
|
|
|
|
void testInit(int tests)
|
|
{
|
|
printf("1..%d\n", tests);
|
|
}
|
|
|
|
void testStartReal(const char *func, const char *name)
|
|
{
|
|
tests++;
|
|
testName = name;
|
|
testFunc = func;
|
|
assertionFailed = 0;
|
|
assertionNum = 0;
|
|
//printf("_____%d: %s: %s...\n", tests, func, name);
|
|
}
|
|
|
|
void testEnd(int result)
|
|
{
|
|
if(result) {
|
|
printf("not ok %d %s: %s\n", tests, testFunc, testName);
|
|
failed++;
|
|
} else {
|
|
printf("ok %d %s: %s\n", tests, testFunc, testName);
|
|
}
|
|
}
|
|
|
|
void testFinish(void)
|
|
{
|
|
if(assertionFailed) {
|
|
printf("not ok %d %s: %s (%d assertions failed.)\n", tests, testFunc, testName, assertionFailed);
|
|
failed++;
|
|
} else {
|
|
printf("ok %d %s: %s (%d assertions passed.)\n", tests, testFunc, testName, assertionNum);
|
|
}
|
|
}
|
|
|
|
void testReport(int expectedTests)
|
|
{
|
|
printf("Total %d tests, %d fails.\n", tests, failed);
|
|
if(failed) exit(-1);
|
|
if(expectedTests != tests) {
|
|
printf("WARNING: the number of the executed tests (%d) is not equal to the expecetd (%d).\n", tests, expectedTests);
|
|
}
|
|
}
|
|
|
|
int testNum(void)
|
|
{
|
|
return tests;
|
|
}
|
|
|
|
void printBinary(unsigned char *data, int length)
|
|
{
|
|
int i;
|
|
|
|
for(i=0; i<length; i++) {
|
|
printf(data[i]?"1":"0");
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void printBstream(BitStream *bstream)
|
|
{
|
|
printBinary(bstream->data, BitStream_size(bstream));
|
|
}
|
|
|
|
void printQRinput(QRinput *input)
|
|
{
|
|
QRinput_List *list;
|
|
int i;
|
|
|
|
list = input->head;
|
|
while(list != NULL) {
|
|
for(i=0; i<list->size; i++) {
|
|
printf("0x%02x,", list->data[i]);
|
|
}
|
|
list = list->next;
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void printQRinputInfo(QRinput *input)
|
|
{
|
|
QRinput_List *list;
|
|
BitStream *b;
|
|
int i, ret;
|
|
|
|
printf("QRinput info:\n");
|
|
printf(" version: %d\n", input->version);
|
|
printf(" level : %c\n", levelChar[input->level]);
|
|
list = input->head;
|
|
i = 0;
|
|
while(list != NULL) {
|
|
i++;
|
|
list = list->next;
|
|
}
|
|
printf(" chunks: %d\n", i);
|
|
b = BitStream_new();
|
|
ret = QRinput_mergeBitStream(input, b);
|
|
if(ret == 0) {
|
|
printf(" bitstream-size: %zu\n", BitStream_size(b));
|
|
BitStream_free(b);
|
|
}
|
|
|
|
list = input->head;
|
|
i = 0;
|
|
while(list != NULL) {
|
|
printf("\t#%d: mode = %s, size = %d\n", i, modeStr[list->mode], list->size);
|
|
i++;
|
|
list = list->next;
|
|
}
|
|
}
|
|
|
|
void printQRinputStruct(QRinput_Struct *s)
|
|
{
|
|
QRinput_InputList *list;
|
|
int i = 1;
|
|
|
|
printf("Struct size: %d\n", s->size);
|
|
printf("Struct parity: %08x\n", s->parity);
|
|
for(list = s->head; list != NULL; list = list->next) {
|
|
printf("Symbol %d - ", i);
|
|
printQRinputInfo(list->input);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void printFrame(int width, unsigned char *frame)
|
|
{
|
|
int x, y;
|
|
|
|
for(y=0; y<width; y++) {
|
|
for(x=0; x<width; x++) {
|
|
printf("%02x ", *frame++);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
void printQRcode(QRcode *code)
|
|
{
|
|
printFrame(code->width, code->data);
|
|
}
|
|
|
|
void printQRRawCodeFromQRinput(QRinput *input)
|
|
{
|
|
QRRawCode *raw;
|
|
int i;
|
|
|
|
puts("QRRawCode dump image:");
|
|
raw = QRraw_new(input);
|
|
if(raw == NULL) {
|
|
puts("Failed to generate QRRawCode from this input.\n");
|
|
return;
|
|
}
|
|
for(i=0; i<raw->dataLength; i++) {
|
|
printf(" %02x", raw->datacode[i]);
|
|
}
|
|
for(i=0; i<raw->eccLength; i++) {
|
|
printf(" %02x", raw->ecccode[i]);
|
|
}
|
|
printf("\n");
|
|
QRraw_free(raw);
|
|
}
|
|
|
|
#if HAVE_SDL
|
|
/* Experimental debug function */
|
|
/* You can call show_QRcode(QRcode *code) to display the QR Code from anywhere
|
|
* in test code using SDL. */
|
|
#include <SDL.h>
|
|
|
|
static void draw_QRcode(QRcode *qrcode, int ox, int oy, int margin, int size, SDL_Surface *surface)
|
|
{
|
|
int x, y, width;
|
|
unsigned char *p;
|
|
SDL_Rect rect;
|
|
Uint32 color[2];
|
|
|
|
color[0] = SDL_MapRGBA(surface->format, 255, 255, 255, 255);
|
|
color[1] = SDL_MapRGBA(surface->format, 0, 0, 0, 255);
|
|
SDL_FillRect(surface, NULL, color[0]);
|
|
|
|
ox += margin * size;
|
|
oy += margin * size;
|
|
width = qrcode->width;
|
|
p = qrcode->data;
|
|
for(y=0; y<width; y++) {
|
|
for(x=0; x<width; x++) {
|
|
rect.x = ox + x * size;
|
|
rect.y = oy + y * size;
|
|
rect.w = size;
|
|
rect.h = size;
|
|
SDL_FillRect(surface, &rect, color[*p&1]);
|
|
p++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void show_QRcode(QRcode *qrcode)
|
|
{
|
|
SDL_Event event;
|
|
SDL_Window *window;
|
|
SDL_Renderer *renderer;
|
|
SDL_Surface *surface;
|
|
SDL_Texture *texture;
|
|
|
|
if(!SDL_WasInit(SDL_INIT_VIDEO)) {
|
|
SDL_Init(SDL_INIT_VIDEO);
|
|
atexit(SDL_Quit);
|
|
}
|
|
int width = (qrcode->width + 4 * 2) * 4; //maring = 4, size = 4
|
|
SDL_CreateWindowAndRenderer(width, width, SDL_WINDOW_SHOWN, &window, &renderer);
|
|
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
|
SDL_RenderClear(renderer);
|
|
surface = SDL_CreateRGBSurface(0, width, width, 32, 0, 0, 0, 0);
|
|
|
|
draw_QRcode(qrcode, 0, 0, 4, 4, surface);
|
|
|
|
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
|
SDL_RenderPresent(renderer);
|
|
fprintf(stderr, "Press any key on the QR Code window to proceed.\n");
|
|
|
|
int loop = 1;
|
|
while(loop) {
|
|
SDL_WaitEvent(&event);
|
|
if(event.type == SDL_KEYDOWN) {
|
|
loop = 0;
|
|
}
|
|
}
|
|
|
|
SDL_FreeSurface(surface);
|
|
SDL_DestroyTexture(texture);
|
|
SDL_DestroyRenderer(renderer);
|
|
}
|
|
#else
|
|
void show_QRcode(QRcode *qrcode) {
|
|
}
|
|
#endif
|