17 #define ERROR_IF(cond, message) if (cond) { printf(message); return -1; };    18 #define MAX_FILENAME_LENGTH 255    29 int main(
int argc, 
char * argv[]) {
    30   ERROR_IF(argc != 2, 
"Usage: inliner source.png");
    31   const char * inputPath = argv[1];
    33   FILE * inputFile = fopen(inputPath, 
"rb");
    34   ERROR_IF(inputFile == 
NULL, 
"Error: could not open input file.");
    36   unsigned char magic[8];
    37   fread(magic, 1, 8, inputFile);
    38   ERROR_IF(png_sig_cmp(magic, 0, 8), 
"Error: Input file is not a PNG file");
    40   png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 
NULL, 
NULL, 
NULL);
    43   png_infop info = png_create_info_struct(png);
    46   png_init_io(png, inputFile);
    47   png_set_sig_bytes(png, 8);
    49   png_read_info(png, info);
    51   png_uint_32 width = png_get_image_width(png, info);
    52   png_uint_32 height = png_get_image_height(png, info);
    53   png_byte colorType = png_get_color_type(png, info);
    54   png_byte bitDepth = png_get_bit_depth(png, info);
    56   ERROR_IF(colorType != PNG_COLOR_TYPE_RGB_ALPHA, 
"Error: Inliner only handles RGBA PNG images.");
    57   ERROR_IF(bitDepth != 8, 
"Error: Inliner only handles RGBA8888 PNG images.");
    59   png_bytep * rowPointers = (png_bytep *)
malloc(
sizeof(png_bytep)*height);
    60   for (
int i=0; i<height; i++) {
    61     rowPointers[i] = (png_byte *)
malloc(png_get_rowbytes(png, info));
    63   png_read_image(png, rowPointers);
    68   const char * inputFileName = inputPath;
    70   for (
const char * currentChar=inputPath; *currentChar != 0; currentChar++) {
    71     if (*currentChar == 
'/') {
    72       inputFileName = currentChar+1;
    81   size_t pathLength = 
strlen(inputPath);
    82   strcpy(headerPath, inputPath);
    84   headerPath[pathLength-3] = 
'h';
    85   headerPath[pathLength-2] = 0;
    88   strcpy(implementationPath, inputPath);
    90   implementationPath[pathLength-3] = 
'c';
    91   implementationPath[pathLength-2] = 
'p';
    92   implementationPath[pathLength-1] = 
'p';
    94   FILE * header = fopen(headerPath, 
"w");
    98   FILE * implementation = fopen(implementationPath, 
"w");
   100   fclose(implementation);
   106   for (
int i=0; i<maxLength; i++) {
   107     snakeCaseName[i] = fileName[i];
   108     if (fileName[i] == 
'.') {
   109       snakeCaseName[i] = 0;
   113   snakeCaseName[maxLength-1] = 0;
   117   for (
int i=0; i<maxLength; i++) {
   118     upperSnakeCaseName[i] = toupper(snakeCaseName[i]);
   124   for (
int i=0; i<maxLength; i++) {
   125     char nextLetter = snakeCaseName[i];
   126     if (nextLetter == 
'_') {
   129     if (i==0 || snakeCaseName[i-1] == 
'_') {
   130       nextLetter = upperSnakeCaseName[i];
   132     camelCaseName[j++] = nextLetter;
   134   camelCaseName[j] = 0;
   138   fprintf(file, 
"// This file is auto-generated by Inliner. Do not edit manually.\n");
   139   fprintf(file, 
"#ifndef IMAGE_STORE_%s_H\n", guardian);
   140   fprintf(file, 
"#define IMAGE_STORE_%s_H\n\n", guardian);
   141   fprintf(file, 
"#include <escher/image.h>\n\n");
   142   fprintf(file, 
"namespace ImageStore {\n\n");
   143   fprintf(file, 
"extern const Image * %s;\n\n", variable);
   144   fprintf(file, 
"};\n\n");
   145   fprintf(file, 
"#endif\n");
   149   fprintf(file, 
"// This file is auto-generated by Inliner. Do not edit manually.\n");
   150   fprintf(file, 
"#include \"%s.h\"\n\n", header);
   151   fprintf(file, 
"#define P(c) KDColor::RGB24(c)\n\n");
   152   fprintf(file, 
"const KDColor pixels[] = {");
   153   for (
int j=0; j<height; j++) {
   154     png_bytep pixelRow = pixelsRowPointers[j];
   155     for (
int i=0; i<width; i++) {
   156       if ((i+j*width) % 6 == 0) {
   157         fprintf(file, 
"\n  ");
   161       png_bytep pixel = &(pixelRow[i*4]);
   162       double red = pixel[0]/255.0;
   163       double green = pixel[1]/255.0;
   164       double blue = pixel[2]/255.0;
   165       double alpha = pixel[3]/255.0;
   167       double blendedRed = red*alpha + 1.0*(1.0-alpha);
   168       double blendedGreen = green*alpha + 1.0*(1.0-alpha);
   169       double blendedBlue = blue*alpha + 1.0*(1.0-alpha);
   170       fprintf(file, 
"P(0x%02X%02X%02X)", (
int)(blendedRed*0xFF), (
int)(blendedGreen*0xFF), (
int)(blendedBlue*0xFF));
   171       if (i!=width-1 || j!= height-1) {
   176   fprintf(file, 
"\n};\n\n");
   177   fprintf(file, 
"constexpr Image image = Image(%d, %d, pixels);\n\n", width, height);
   178   fprintf(file, 
"const Image * ImageStore::%s = ℑ\n", variable);
 #define ERROR_IF(cond, message)
 
void generateHeaderFromImage(FILE *file, const char *guardian, const char *variable)
 
int main(int argc, char *argv[])
 
void camelCaseNameFromSnakeCaseNames(const char *snakeCaseName, const char *upperSnakeCaseName, char *camelCaseName, size_t maxLength)
 
size_t strlen(const char *s)
 
void * malloc(size_t size)
 
#define MAX_FILENAME_LENGTH
 
void generateImplementationFromImage(FILE *file, const char *header, const char *variable, uint32_t width, uint32_t height, png_bytep *pixelsRowPointers)
 
void fileNameToSnakeCaseName(const char *fileName, char *snakeCaseName, size_t maxLength)
 
void snakeCaseNameToUpperSnakeName(const char *snakeCaseName, char *upperSnakeCaseName, size_t maxLength)