aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoriceyrazor <iceyrazor@mailfence.com>2026-03-13 20:25:06 -0500
committericeyrazor <iceyrazor@mailfence.com>2026-03-13 20:25:06 -0500
commitd8d1ab660b2dc0e6d9d41d80c2f869a918f0aa9e (patch)
treec08d5002c63b3050f8d71f8477f04b5dd6ce5bad /src
parent801c119f1f44ea7509e705af416ecb23e5167e28 (diff)
project restructure
- created build.sh - changed window name - font is now definition - readme change
Diffstat (limited to 'src')
-rwxr-xr-xsrc/main.c380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100755
index 0000000..a8a18b3
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,380 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <math.h>
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_video.h>
+#include <SDL2/SDL_image.h>
+#include <SDL2/SDL_ttf.h>
+
+#define conf_font "/usr/share/fonts/TTF/Inconsolata-Regular.ttf"
+
+
+float map(float value, float start1, float stop1, float start2, float stop2){
+ return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
+}
+
+void putPixelRGB(SDL_Renderer* renderer, int x, int y, unsigned char r,unsigned char g,unsigned char b){
+SDL_SetRenderDrawColor(renderer,(Uint8)r,(Uint8)g,(Uint8)b,255);
+SDL_RenderDrawPoint(renderer,x,y);
+}
+
+
+static int SDL_CalculatePitch(Uint32 format, int width)
+{
+ int pitch;
+
+ if (SDL_ISPIXELFORMAT_FOURCC(format) || SDL_BITSPERPIXEL(format) >= 8) {
+ pitch = (width * SDL_BYTESPERPIXEL(format));
+ } else {
+ pitch = ((width * SDL_BITSPERPIXEL(format)) + 7) / 8;
+ }
+ pitch = (pitch + 3) & ~3; /* 4-byte aligning for speed */
+ return pitch;
+}
+
+SDL_Texture *createText(char *string, SDL_Renderer *renderer, SDL_Rect *textRect,TTF_Font *font, SDL_Color color){
+
+ SDL_Surface *textSurface = TTF_RenderText_Solid_Wrapped(font,string,color,400);
+ SDL_Texture *text = SDL_CreateTextureFromSurface(renderer, textSurface);
+
+ SDL_QueryTexture(text, NULL, NULL, &textRect->w, &textRect->h);
+
+ SDL_FreeSurface(textSurface);
+ return text;
+}
+
+typedef struct{
+ char *file;
+ int color;
+ char *density;
+ int height;
+ int width;
+ int char_size;
+ int box_size;
+ bool export;
+ char *export_name;
+ bool print;
+ float brightness;
+} Pargs;
+
+void arg_interpet(char *argv[], Pargs *pargs){
+ int i=1;
+ if(argv[i]){
+ while (argv[i]) {
+
+ if (strcmp(argv[i],"--help")==0){
+ printf("--help prints this message\n");
+ printf("-p print the ascii to terminal\n");
+ printf("-c [color] sets the color type. none, avg, color\n");
+ printf("-d [str] sets the characters to use\n");
+ printf("-w [width]\n");
+ printf("-h [height]\n");
+ printf("-s [size] sets the character size\n");
+ printf("-b [size] sets the box size\n");
+ printf("-o [file.png] exports the image\n");
+ printf("-b [brightness float] sets brightness\n");
+ printf("defaults \n none \n N@EW$9876543210?!abc;:+=-,._ \n width 900 \n height 900 \n char size 10 \n box size 10");
+ exit(0);
+ }
+
+ if (argv[i+1]){}else{
+ pargs->file=argv[i];
+ break;
+ }
+
+ if (strcmp(argv[i],"-p")==0){
+ pargs->print=true;
+ }
+
+ if (strcmp(argv[i],"-c")==0){
+ if(argv[i+2]){}else{
+ printf("you must specify a color with -C\n\n");
+ exit(1);
+ }
+
+ if(strcmp(argv[i+1],"none")==0){
+ pargs->color=0;
+ }
+ else if (strcmp(argv[i+1],"avg")==0) {
+ pargs->color=1;
+ }
+ else if (strcmp(argv[i+1],"color")==0) {
+ pargs->color=2;
+ }
+ else {
+ printf("not a valid color type\n\n");
+ exit(1);
+ }
+ }
+
+ if (strcmp(argv[i],"-d")==0){
+ if(argv[i+2]){}else{
+ printf("you must select a charset with -d \n\n");
+ exit(1);
+ }
+
+ pargs->density=argv[i+1];
+ }
+
+ if (strcmp(argv[i],"-B")==0){
+ if(argv[i+2]){}else{
+ printf("you must select brightness with -B \n\n");
+ exit(1);
+ }
+
+ pargs->brightness=atof(argv[i+1]);
+ }
+
+ if (strcmp(argv[i],"-w")==0){
+ if(argv[i+2]){}else{
+ printf("you must set width -w \n\n");
+ exit(1);
+ }
+
+ pargs->width=atoi(argv[i+1]);
+ }
+
+ if (strcmp(argv[i],"-h")==0){
+ if(argv[i+2]){}else{
+ printf("you must set height -h \n\n");
+ exit(1);
+ }
+
+ pargs->height=atoi(argv[i+1]);
+ }
+
+ if (strcmp(argv[i],"-s")==0){
+ if(argv[i+2]){}else{
+ printf("you must set char_size with -s \n\n");
+ exit(1);
+ }
+
+ pargs->char_size=atoi(argv[i+1]);
+ }
+
+ if (strcmp(argv[i],"-b")==0){
+ if(argv[i+2]){}else{
+ printf("you must set box_size with -b \n\n");
+ exit(1);
+ }
+
+ pargs->box_size=atoi(argv[i+1]);
+ }
+
+ if (strcmp(argv[i],"-o")==0){
+ if(argv[i+2]){}else{
+ printf("you must set image export name with -o \n\n");
+ exit(1);
+ }
+
+ pargs->export=true;
+ pargs->export_name=argv[i+1];
+ }
+
+ argv++;
+ }
+ } else {
+ printf("error, file not specified");
+ exit(1);
+ }
+
+}
+
+void draw(SDL_Renderer* renderer,SDL_Window* window, uint32_t pix_format,TTF_Font *font,Pargs *parsed_args){
+
+ SDL_Rect textRect;
+ memset(&textRect, 0, sizeof(SDL_Rect));
+ textRect.w = parsed_args->width;
+ textRect.h = parsed_args->height;
+
+ SDL_Rect textRect2={0,0,0,0};
+ textRect2.w = textRect2.h = 10;
+
+ //SDL_Rect *textRect2=malloc(sizeof(SDL_Rect));
+ //textRect2->w = textRect2->h = 10;
+
+
+
+ SDL_Texture *textllure;
+ textllure=IMG_LoadTexture(renderer,parsed_args->file);
+
+ SDL_RenderCopy(renderer, textllure, NULL, &textRect);
+
+ Uint32* Rpixels = (Uint32*)malloc(parsed_args->width * parsed_args->height * 2 * sizeof(Uint32));
+
+ int pitch = SDL_CalculatePitch(pix_format, parsed_args->width);
+ //int a=SDL_RenderReadPixels(renderer, NULL, pix_format, Rpixels, parsed_args->width * sizeof(Uint32));
+ int a=SDL_RenderReadPixels(renderer, NULL, pix_format, Rpixels, pitch);
+
+ for (int width=0; width<=parsed_args->width; width++){
+ for (int height=0; height<=parsed_args->height; height++){
+ putPixelRGB(renderer, width, height, 0, 0, 0);
+ }
+ }
+
+ char *sel_char;
+ sel_char = (char *) malloc(sizeof(char) * 2);
+ SDL_Texture *textllure2;
+
+ const int divis=parsed_args->box_size;
+ const int w2 = parsed_args->width / divis;
+ const int h2 = parsed_args->height / divis;
+
+ for (int y=0; y<h2; y++){
+ for (int x=0; x<w2; x++){
+ int x2=x * divis;
+ int y2=y * divis;
+ if(x2>parsed_args->width){x2=parsed_args->width;}
+ if(y2>parsed_args->height){y2=parsed_args->height;}
+
+
+ const Uint32 pixelIndex= Rpixels[x2 + y2 * parsed_args->width];
+ uint8_t r2 = round(((pixelIndex >> 16) & 0xFF) * parsed_args->brightness);
+ uint8_t g2 = round(((pixelIndex >> 8) & 0xFF) * parsed_args->brightness);
+ uint8_t b2 = round((pixelIndex & 0xFF) * parsed_args->brightness);
+
+ if(r2 > 255){ r2=255; }
+ if(b2 > 255){ b2=255; }
+ if(g2 > 255){ g2=255; }
+
+
+
+ int avg = (r2 + g2 + b2) / 3;
+ int avg_conv=avg;
+
+ float inver=255-(avg)-1;
+ if (inver>254){ inver=254; }
+ if (inver<0){ inver=0; }
+
+ const int charIndex = floor(map(inver,0,255,0,strlen(parsed_args->density)));
+
+
+ textRect2.x = x2;
+ textRect2.y = y2;
+ SDL_Color color={255,255,255,255};
+ switch (parsed_args->color){
+ case 1:
+ color.r=avg;
+ color.b=avg;
+ color.g=avg;
+ break;
+
+ case 2:
+ color.r=r2;
+ color.b=b2;
+ color.g=g2;
+ break;
+ }
+
+ sel_char[0]=parsed_args->density[charIndex];
+ sel_char[1]='\0';
+ if(parsed_args->print==true){printf("%s",sel_char);}
+ //SDL_Log("%dx%d %d %d %s\n",width2,height2,avg_conv,charIndex,sel_char);
+
+ textllure2=createText(sel_char, renderer, &textRect2, font, color);
+ SDL_RenderCopy(renderer,textllure2,NULL, &textRect2);
+ SDL_DestroyTexture(textllure2);
+
+ }
+ if(parsed_args->print==true){printf("\n");}
+ }
+
+
+
+ //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
+ if(parsed_args->export==true){
+ SDL_Surface* pScreenShot = SDL_CreateRGBSurface(0, parsed_args->width, parsed_args->height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
+ //SDL_Surface* pScreenShot = SDL_CreateRGBSurface(0, parsed_args->width, parsed_args->height, 32, 0,0,0,0);
+
+ if(pScreenShot)
+ {
+ // Read the pixels from the current render target and save them onto the surface
+ //SDL_RenderReadPixels(renderer, NULL, SDL_GetWindowPixelFormat(window), pScreenShot->pixels, pScreenShot->pitch);
+ SDL_RenderReadPixels(renderer, NULL, SDL_GetWindowPixelFormat(window), pScreenShot->pixels, pScreenShot->pitch);
+
+ char num[100];
+ char* name=parsed_args->export_name;
+
+ // Create the bmp screenshot file
+ IMG_SavePNG(pScreenShot, name);
+
+ // Destroy the screenshot surface
+ SDL_FreeSurface(pScreenShot);
+ }
+ }
+
+ SDL_RenderPresent(renderer);
+ SDL_UpdateWindowSurface(window);
+ free(Rpixels);
+ free(sel_char);
+ SDL_DestroyTexture(textllure);
+ SDL_DestroyTexture(textllure2);
+
+}
+
+int main(int argc, char *argv[])
+{
+ Pargs parsed_args={"",0,"N@EW$9876543210?!abc;:+=-,._ ",900,900,10,10,false,"",false,1};
+ arg_interpet(argv,&parsed_args);
+
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
+ SDL_Log("SDL fails to initialize! %s\n", SDL_GetError());
+ TTF_Init();
+
+
+
+ SDL_Window *window = SDL_CreateWindow("SDL Ascii", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, parsed_args.width, parsed_args.height, SDL_WINDOW_SHOWN);
+ if (!window) {
+ printf("Failed to create window: %s\n", SDL_GetError());
+ }
+ SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_SOFTWARE);
+ if (!renderer) {
+ printf("Failed to create renderer: %s\n", SDL_GetError());
+ }
+
+
+ uint32_t wnd_pix_fmt = SDL_GetWindowPixelFormat(window);
+
+ TTF_Font *font = TTF_OpenFont(conf_font,parsed_args.char_size);
+
+
+ draw(renderer,window,wnd_pix_fmt,font,&parsed_args);
+
+
+ bool quit = false;
+ SDL_Event e;
+ bool mousedown=false;
+ int gmouseX=0;
+ int gmouseY=0;
+ while (!quit) {
+ while (SDL_PollEvent(&e)) {
+ if (e.type == SDL_QUIT) {
+ quit = true;
+ }
+ else if(e.type == SDL_MOUSEBUTTONDOWN){
+ } else if(e.type==SDL_MOUSEBUTTONUP){
+ }
+ gmouseX=e.button.x;
+ gmouseY=e.button.y;
+ }
+ float mouseoutX=gmouseX;
+ float mouseoutY=gmouseY;
+ if(mousedown==true){
+ }
+ SDL_Delay(10);
+ }
+
+ SDL_DestroyWindow(window);
+ //free window and windowSurface
+ SDL_DestroyRenderer(renderer);
+ TTF_CloseFont(font);
+ SDL_VideoQuit();
+ TTF_Quit();
+ SDL_Quit();
+
+
+ return 0;
+}