diff --git a/main.c b/main.c index 39a6210..316cb9f 100644 --- a/main.c +++ b/main.c @@ -32,7 +32,7 @@ unsigned int nearest_power_of_2(unsigned int n) { } struct options { - int r; + uint32_t r; int s; uint8_t c; int o; @@ -68,9 +68,7 @@ void printHelp() { ); } -void printNoFrames() { - printf("You need to specify at least one frame to use, goober.\n"); -} +void printNoFrames() { printf("You need to specify at least one frame to use, goober.\n"); } int main(const int argc, char *argv[]) { printf( @@ -80,6 +78,7 @@ int main(const int argc, char *argv[]) { "\n" ); if (argc < 2) { printHelp(); return 0; } + // Strings allocated with variable size according to filename need to be done on the heap due to an MSVC bug. char* filename = (char*)malloc(strlen(argv[1])*sizeof(char)); // MSVC strcpy(filename, argv[1]); printf("Creating avatar %s.mov\n", filename); @@ -108,21 +107,32 @@ int main(const int argc, char *argv[]) { printf("Adding frame to search index: %s\n", frames[numFrames]); numFrames++; - } else if (argv[i] == "-r") { - + } else if (strcmp(argv[i], "-r") == 0) { + if (i == argc-1) { printf("No parameter for option: -r\n"); return 0; } + int r = pow(2, trunc(atof(argv[i+1]))); + if (r > 4096) { printf("I really, really hope your image is not %d pixels in size.\n", r); } + else if (r < 2) {printf("I'm sorry, Dave, I'm afraid I can't do that. (%d pixel(s) is too small, clamping to 2.)\n", r); r = 2;} + printf("Limiting resolution per frame to %dx%d pixels.\n", r, r); + opt.r = r; + i++; } else if (strcmp(argv[i], "-s") == 0) { - opt.s = 1; - } else if (argv[i] == "-o") { - - } else if (argv[i] == "-b") { - + opt.s = !opt.s; + } else if (strcmp(argv[i], "-o") == 0) { + opt.o = !opt.o; + } else if (strcmp(argv[i], "-c") == 0) { + if (i == argc-1) { printf("No parameter for option: -c\n"); return 0; } + const int c = trunc(atof(argv[i+1])); + if (c < 1 || c > 256) { printf("Invalid number of colors: %s\n", argv[i+1]); return 0; } + opt.c = c - 1; + i++; } else { printf("I don't know what \"%s\" means!\n", argv[i]); return 0; } i++; } - printf("Importing %d frames...\n", numFrames); + if (numFrames == 0) { printNoFrames(); return 0; } + if (MagickReadImage(mw, frames[0]) == MagickFalse) { printf("ERROR trying to read %s\n", frames[0]); return 0;} MagickSetImageFormat(mw, "BMP3"); MagickSetImageDepth(mw, 8); @@ -131,6 +141,57 @@ int main(const int argc, char *argv[]) { uint16_t width = MagickGetImageWidth(mw); uint16_t height = MagickGetImageHeight(mw); + // -r option + if (opt.r > 0) { + if (opt.s > 0) { + printf("Squishing to resolution limit...\n"); + if (width > opt.r) { + MagickResizeImage(mw, nearest_power_of_2(width), nearest_power_of_2(height), LanczosFilter); + width = opt.r; + } + if (height > opt.r) { + MagickResizeImage(mw, nearest_power_of_2(width), nearest_power_of_2(height), LanczosFilter); + height = opt.r; + } + } + else { + printf("Fitting to resolution limit...\n"); + if (width > opt.r || height > opt.r) { + if (width > height) { + const double ratio = (double)height/(double)width; + printf("Letterboxing image to %ux%u.\n", opt.r, opt.r*ratio); + PixelWand* pw = NewPixelWand(); + MagickGetImagePixelColor(mw, 0, 0, pw); + MagickSetImageBackgroundColor(mw, pw); + + if (ratio < 1) MagickResizeImage(mw, opt.r, opt.r*ratio, LanczosFilter); + //MagickExtentImage(mw, opt.r, opt.r, 0, (opt.r-(opt.r*ratio))*-0.5); + + width = opt.r; + height = opt.r; + } else if (height > width) { + const double ratio = (double)width / (double)height; + printf("Pillarboxing image to %ux%u.\n", opt.r*ratio, opt.r); + PixelWand* pw = NewPixelWand(); + MagickGetImagePixelColor(mw, 0, 0, pw); + MagickSetImageBackgroundColor(mw, pw); + + if (ratio < 1) MagickResizeImage(mw, opt.r*ratio, opt.r, LanczosFilter); + //MagickExtentImage(mw, opt.r, opt.r, (opt.r-(opt.r*ratio))*-0.5, 0); + + width = opt.r; + height = opt.r; + } else /*if (height == width)*/ { + printf("Resizing image to %ux%u.\n", opt.r, opt.r); + MagickResizeImage(mw, opt.r, opt.r, LanczosFilter); + + width = opt.r; + height = opt.r; + } + } + } + } + if (!isPowerOfTwo(width) || !isPowerOfTwo(height)) printf("Uh-oh! Image size %hux%hu is not a power of two!\n", width, height); if (opt.s > 0 || (!isPowerOfTwo(width) && !isPowerOfTwo(height))) { // both are bad! printf("Resizing image to %ux%u.\n", nearest_power_of_2(width), nearest_power_of_2(height)); @@ -162,6 +223,8 @@ int main(const int argc, char *argv[]) { double ratio2; PixelWand* pw = NewPixelWand(); MagickGetImagePixelColor(mw, 0, 0, pw); + + printf("Importing %d frames...\n", numFrames); i = 1; while (i < numFrames) { // Letterbox background default to transparent pixel @@ -240,7 +303,7 @@ int main(const int argc, char *argv[]) { // Pass on images to COMPIMG printf("Encoding texture file...\n"); - char* command = (char*)malloc((54 + 3 * opt.o + strlen(filename))*sizeof(char)); // MSVC + char* command = (char*)malloc((54 + 3 * abs(1-opt.o) + strlen(filename))*sizeof(char)); // MSVC char argTransparent[3]; if (opt.o == 0) sprintf(argTransparent, " -t"); #ifdef _MSC_VER @@ -248,6 +311,7 @@ int main(const int argc, char *argv[]) { #else sprintf(command, "./compimg.exe -ace -c%d -r0 -pt%s -emov -M%s +segments.txt", opt.c+1, argTransparent, filename); #endif + printf("%s\n", command); if (system(command)) { printf("ERROR trying to run COMPIMG!\n"); return 0; } printf("\n\n!!! DONE !!!\nYour avatar name is: %s%ds*%dh*%dv*.mov\n", filename, numFrames, piecesX, piecesY);