167 lines
4.1 KiB
C
167 lines
4.1 KiB
C
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_error.h>
|
|
#include <SDL2/SDL_events.h>
|
|
#include <SDL2/SDL_log.h>
|
|
#include <SDL2/SDL_render.h>
|
|
#include <SDL2/SDL_video.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
void render_image(SDL_Renderer *ref_renderer, unsigned char *data,
|
|
unsigned long w, unsigned long h);
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if (argc < 2) {
|
|
fprintf(stderr, "Argumentos invalidos\n");
|
|
return 1;
|
|
}
|
|
|
|
char *fname;
|
|
|
|
fname = strdup(argv[1]);
|
|
|
|
if (fname == NULL) {
|
|
perror("strdup");
|
|
return 1;
|
|
}
|
|
|
|
FILE *pfile = fopen(fname, "rb");
|
|
|
|
if (pfile == NULL) {
|
|
perror("fopen");
|
|
fclose(pfile);
|
|
return 1;
|
|
}
|
|
|
|
uint8_t *header = NULL;
|
|
|
|
header = malloc(sizeof(uint8_t) * 3);
|
|
|
|
printf("El sizeof de header es: %d\n", (int)sizeof(header));
|
|
|
|
if (fread(header, sizeof(uint8_t) * 2, 1, pfile) == 0) {
|
|
perror("fread");
|
|
fclose(pfile);
|
|
return 1;
|
|
}
|
|
|
|
header[3] = '\0';
|
|
|
|
int w, h, s;
|
|
|
|
if (fscanf(pfile, " %d %d %d", &w, &h, &s) != 3) {
|
|
fprintf(stderr, "Error leyendo las caracteristicas de la imagen.\n");
|
|
fclose(pfile);
|
|
return 1;
|
|
}
|
|
|
|
fprintf(stdout, "Header readed: %s\n", (unsigned char *)header);
|
|
fprintf(stdout,
|
|
"Las dimensiones son %dx%d pixeles y una escala maxima de color de "
|
|
"%d\n",
|
|
w, h, s);
|
|
|
|
// consumo un caracter mas y queda listo para leer los datos de los pixeles.
|
|
fgetc(pfile);
|
|
|
|
unsigned char *data = NULL;
|
|
unsigned long pixel_count = w * h;
|
|
|
|
data = malloc(sizeof(data) * pixel_count * 3);
|
|
|
|
if (data == NULL) {
|
|
perror("malloc");
|
|
fclose(pfile);
|
|
return 1;
|
|
}
|
|
|
|
unsigned long readed =
|
|
fread(data, sizeof(unsigned char) * 3, pixel_count, pfile);
|
|
|
|
fprintf(stdout, "%zu pixeles leidos de %zu\n", readed, pixel_count);
|
|
|
|
if (readed != pixel_count) {
|
|
fprintf(stderr, "Error leyendo datos del archivo\n");
|
|
free(data);
|
|
fclose(pfile);
|
|
}
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
|
perror("SLD_Init");
|
|
free(data);
|
|
fclose(pfile);
|
|
return 1;
|
|
}
|
|
|
|
SDL_Window *window =
|
|
SDL_CreateWindow("Visor de imagenes", SDL_WINDOWPOS_CENTERED,
|
|
SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_SHOWN);
|
|
|
|
if (window == NULL) {
|
|
SDL_Log("SLD_WINDOW: %s", SDL_GetError());
|
|
SDL_Quit();
|
|
free(data);
|
|
fclose(pfile);
|
|
return 1;
|
|
}
|
|
|
|
SDL_Renderer *renderer = SDL_CreateRenderer(
|
|
window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
|
|
|
if (!renderer) {
|
|
SDL_Log("No se pudo crear el renderizador: %s", SDL_GetError());
|
|
SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
free(data);
|
|
fclose(pfile);
|
|
return 1;
|
|
}
|
|
|
|
bool running = true;
|
|
SDL_Event ev;
|
|
while (running) {
|
|
while (SDL_PollEvent(&ev)) {
|
|
if (ev.type == SDL_QUIT) {
|
|
running = 0; // Si hacen clic en la "X", salimos
|
|
}
|
|
if (ev.type == SDL_KEYDOWN) {
|
|
// Si presionan Escape, salimos
|
|
if (ev.key.keysym.sym == SDLK_ESCAPE) {
|
|
running = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
SDL_RenderClear(renderer);
|
|
render_image(renderer, data, w, h);
|
|
SDL_RenderPresent(renderer);
|
|
}
|
|
|
|
SDL_DestroyRenderer(renderer);
|
|
SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
|
|
free(data);
|
|
fclose(pfile);
|
|
return 0;
|
|
}
|
|
|
|
void render_image(SDL_Renderer *ref_renderer, unsigned char *rdata,
|
|
unsigned long int w, unsigned long h) {
|
|
|
|
unsigned long offset = 0;
|
|
for (unsigned long cury = 0; cury < h; cury++) {
|
|
for (unsigned long curx = 0; curx < w; curx++) {
|
|
uint8_t r = *(rdata + offset++);
|
|
uint8_t g = *(rdata + offset++);
|
|
uint8_t b = *(rdata + offset++);
|
|
|
|
SDL_SetRenderDrawColor(ref_renderer, r, g, b, 255);
|
|
SDL_RenderDrawPoint(ref_renderer, curx, cury);
|
|
}
|
|
}
|
|
}
|