-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreador_archivo_pbm.c
159 lines (150 loc) · 4.82 KB
/
creador_archivo_pbm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "creador_archivo_pbm.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//Valores de retorno
#define EXITO 0
#define ERROR -1
//Opcion de apertura
#define NUEVO_ARCHIVO_ESCRITURA "w"
//Configuraciones formato pbm
#define EXTENSION_ARCHIVO ".pbm"
#define MAGIC_NUMBER "P1\n"
//Tamanios de buffer
#define TAM_BUFFER_ANCHO_Y_ALTO 128
#define TAM_BUFFER_CONTADOR 3
#define ESPACIO_PARA_FORMATO 9 //Fin de cadena + sufijo _000.pbm
enum ESTADOS_CELDA {APAGADA = '0', PRENDIDA = '1'};
//////////////Funciones privadas///////////////////
/*
Crea una linea para ser escrita en el archivo de formato .pbm
La linea es conformada teniendo en cuenta el factor de escala y
los valores del tablero en la posicion y.
Esta funcion no falla.
*/
static void _crear_linea(creador_archivo_pbm_t *self, unsigned char **tablero, const unsigned int y){
int cont = 0;
for (int x=0; x<self->N; x++){
for (int k=0; k<self->escala; k++){
if (tablero[y][x]){
self->linea[cont] = PRENDIDA;
}else{
self->linea[cont] = APAGADA;
}
cont++;
}
}
self->linea[cont] = '\n';
}
/*
Actualiza el nombre del archivo actual segun el contador de archivos creados
No falla
*/
static void _actualizar_nombre_archivo(creador_archivo_pbm_t *self){
snprintf(self->nombre_archivo,
self->tam_nombre_archivo,
"%s_%03d%s",
self->prefijo,
self->contador,
EXTENSION_ARCHIVO);
}
/*
Escribe los parametros iniciales al comienzo del archivo de formato .pbm
Estos parametros son:
- "Magic number" que representa la version del formato, ej: P1, P4.
- Ancho y alto de la imagen medido en pixeles.
Esta funcion no falla.
*/
static void _inicializar_archivo(creador_archivo_pbm_t *self, FILE* archivo){
char ancho_y_alto[TAM_BUFFER_ANCHO_Y_ALTO] = {0};
snprintf(ancho_y_alto,
TAM_BUFFER_ANCHO_Y_ALTO,
"%d %d\n",
self->N*self->escala,
self->M*self->escala);
fputs(MAGIC_NUMBER, archivo);
fputs(ancho_y_alto, archivo);
}
//////////////Funciones publicas///////////////////
int creador_archivo_pbm_crear(creador_archivo_pbm_t *self,
const char* prefijo,
const unsigned int M,
const unsigned int N,
const unsigned int escala){
self->M = M;
self->N = N;
self->escala = escala;
self->contador = 1;
long unsigned int largo_prefijo = strlen(prefijo);
self->prefijo = calloc(largo_prefijo + 1, sizeof(char));
if (!self->prefijo) return ERROR;
memcpy(self->prefijo, prefijo, largo_prefijo);
self->tam_nombre_archivo = largo_prefijo + ESPACIO_PARA_FORMATO;
self->nombre_archivo = calloc(self->tam_nombre_archivo, sizeof(char));
if (!self->nombre_archivo){
free(self->prefijo);
self->prefijo = NULL;
self->tam_nombre_archivo = 0;
return ERROR;
}
//Dos bytes de mas para el fin de cadena y el salto de linea
self->linea = calloc((self->N)*self->escala+2, sizeof(char));
if (!self->linea){
free(self->prefijo);
free(self->nombre_archivo);
self->nombre_archivo = NULL;
self->prefijo = NULL;
self->tam_nombre_archivo = 0;
}
return EXITO;
}
void creador_archivo_pbm_destruir(creador_archivo_pbm_t *self){
if (self->prefijo){
free(self->prefijo);
self->prefijo = NULL;
}
if (self->nombre_archivo){
free(self->nombre_archivo);
self->nombre_archivo = NULL;
}
if (self->linea){
free(self->linea);
self->linea = NULL;
}
}
int creador_archivo_pbm_nuevo_archivo(creador_archivo_pbm_t *self, unsigned char** tablero){
_actualizar_nombre_archivo(self);
FILE *archivo = fopen(self->nombre_archivo, NUEVO_ARCHIVO_ESCRITURA);
if (!archivo) return ERROR;
_inicializar_archivo(self, archivo);
int estado = EXITO;
for (int y=0; y<self->M; y++){
for (int k=0; k<self->escala; k++){
_crear_linea(self, tablero, y);
if(fputs(self->linea, archivo) == EOF){
estado = ERROR;
break;
}
}
}
//Pongo aca el mensaje para imprimir error en caso de error
//Hace algo similar a un clear en la pantalla
printf("\e[1;1H\e[2J");
printf(" ");
if (estado == ERROR){
fprintf(stdout,
"Error al grabar %s_%d%s\n",
self->prefijo,
self->contador,
EXTENSION_ARCHIVO);
}else{
fprintf(stdout,
"Grabando %s_%d%s\n",
self->prefijo,
self->contador,
EXTENSION_ARCHIVO);
}
self->contador++;
fclose(archivo);
return estado;
}