diff --git a/src/img2sparse.c b/src/img2sparse.c index caef226f22a250408d312236f690362a12eded4a..77e3316b2530ac49ce210e156c5032d97c365837 100644 --- a/src/img2sparse.c +++ b/src/img2sparse.c @@ -32,13 +32,134 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. INCLUDE ==============================================================================*/ // C Standard Library +#include <assert.h> #include <stdlib.h> // EXIT_SUCCESS +#include <string.h> +#include <errno.h> +#include <stdbool.h> +#include <stdint.h> // uint32_t, UINT32_MAX // Internal +#include "file_io.h" +#include "log.h" #include "sparse.h" +/*============================================================================== + STATIC +==============================================================================*/ +static struct Logger s_logger = { + .level_flag = LOG_LEVEL_ALL, + .output = LOG_OUTPUT_STDERR +}; /*============================================================================== MAIN ==============================================================================*/ int main(int argc, char * argv[]) { + /*struct Sparse * sparse = Sparse_Create(argv[1], "r"); + Sparse_ReadImage(sparse); + int fd = FIO_Open(args->sparse_path, "w"); + if(fd != -1) { + Sparse_Write(sparse, fd); + FIO_Close(fd); + } else { + Log_Fatal(&s_logger, "FIO_Open(%s, \"w\") : %s\n",args->sparse_path, strerror(errno)); + exit(-1); + } + Sparse_Close(&sparse);*/ + + int fd_in = FIO_Open(argv[1], "r"); + if(fd_in != -1) { + size_t img_size = FIO_GetSize(fd_in); + char * buffer = malloc(img_size); + if(buffer != NULL) { + size_t bytes_read = FIO_Read(fd_in, buffer, img_size); + if(bytes_read == img_size) { + size_t block_size = Sparse_GuessBlockSize(img_size); + block_size = 1024; + if(block_size != 0) { + struct Sparse * sparse = Sparse_Create(block_size, img_size); + size_t chunk_count = 0; + enum Sparse_ChunkType prev_type = CHUNK_TYPE_NONE; + // Need to be allocated once before being able to call realloc() + sparse->chunks = malloc(sizeof(*sparse->chunks)); + for(size_t i = 0; i < sparse->header.block_count; i++) { + enum Sparse_ChunkType curr_type = CHUNK_TYPE_NONE; + size_t block_offset = i * block_size; + size_t sparse_data_size = 0; + for(size_t j = 1; j < sparse->header.block_size; j++) { + if(buffer[block_offset] != buffer[block_offset + j]) { + curr_type = CHUNK_TYPE_RAW; + break; + } + } + if(curr_type != CHUNK_TYPE_RAW) { + sparse_data_size = 4; + //printf("Block %zu = raw\n", i); + if(buffer[block_offset] == 0) { + //printf("Block %zu = dc\n", i); + curr_type = CHUNK_TYPE_DONT_CARE; + } else { + //printf("Block %zu = fill\n", i); + curr_type = CHUNK_TYPE_FILL; + } + } + if(prev_type != curr_type) { + sparse->chunks = realloc(sparse->chunks, sizeof(*sparse->chunks) * (chunk_count + 1)); + sparse->chunks[chunk_count].type = curr_type; + sparse->chunks[chunk_count].size = sparse_data_size; + sparse->chunks[chunk_count].data = buffer + (i * block_size); + chunk_count++; + } + prev_type = curr_type; + } + sparse->header.chunk_count = chunk_count; + int fd_out = FIO_Open(argv[2], "w"); + if(fd_out != -1) { + FIO_Write(fd_out, &sparse->header, sizeof(sparse->header)); + for(size_t i = 0; i < chunk_count; i++) { + FIO_Write(fd_out, &(sparse->chunks[i].type), sizeof(uint16_t)); + FIO_Write(fd_out, &((uint16_t){0}), sizeof(uint16_t)); + size_t img_data_size = (size_t)sparse->chunks[i+1].data - (size_t)sparse->chunks[i].data; + sparse->chunks[i].block_count = img_data_size / 1024; + if(sparse->chunks[i].type == CHUNK_TYPE_RAW) { + sparse->chunks[i].size = img_data_size; + } + if(i == (chunk_count-1)) { + img_data_size = (size_t)(&buffer[img_size]) - (size_t)sparse->chunks[i].data; + printf("last data size = %zu\n", img_data_size); + sparse->chunks[i].block_count = img_data_size / 1024; + } + printf("block count %zu\n", sparse->chunks[i].block_count); + FIO_Write(fd_out, &(sparse->chunks[i].block_count), sizeof(uint32_t)); + FIO_Write(fd_out, &((uint32_t){sparse->chunks[i].size+12}), sizeof(uint32_t)); + printf("%zu - %zu = %zu\n", (size_t)sparse->chunks[i+1].data, (size_t)sparse->chunks[i].data, sparse->chunks[i].size); + FIO_Write(fd_out, sparse->chunks[i].data, sparse->chunks[i].size); + } + Sparse_DumpInfo(sparse); + FIO_Close(fd_out); + } else { + Log_Fatal(&s_logger, "FIO_Open(%s, \"w\") : %s\n",argv[2], strerror(errno)); + exit(-1); + } + /*printf("chunk_count = %zu\n", chunk_count); + for(size_t i = 0; i < chunk_count; i++) { + printf("%zu\t", sparse->chunks[i].type); + printf("%p\n", sparse->chunks[i].data); + }*/ + } else { + Log_Fatal(&s_logger, "Invalid image size!\n", fd_in, strerror(errno)); + exit(-1); + } + } else { + Log_Fatal(&s_logger, "FIO_Read(%d) failed! %s\n", fd_in, strerror(errno)); + exit(-1); + } + free(buffer); + } + FIO_Close(fd_in); + } else { + Log_Fatal(&s_logger, "FIO_Open(%s, \"r\") failed! %s\n", + argv[1], strerror(errno)); + exit(-1); + } return EXIT_SUCCESS; }