/* ***************************************************************************** * decode/mcs/matrix.c -- decode an MCS matrix. * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey * * This file is part of libg1m. * libg1m is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3.0 of the License, * or (at your option) any later version. * * libg1m is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libg1m; if not, see . * ************************************************************************** */ #include /** * g1m_decode_mcs_matrix: * Decode a matrix. * * @arg handle the handle. * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ int g1m_decode_mcs_matrix(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { g1m_mcs_cell_t **tab, *rws; int err = g1m_error_alloc; /* read header */ DREAD(hd, mcs_matheader) /* correct endianess */ hd.width = be16toh(hd.width); hd.height = be16toh(hd.height); /* log info */ uint_fast32_t w = hd.width, h = hd.height; log_info("Matrix size is %" PRIuFAST32 "*%" PRIuFAST32, w, h); /* store dimensions */ handle->head.width = w; handle->head.height = h; handle->cells = NULL; if (w && h) { /* alloc real matrix */ tab = malloc(sizeof(g1m_mcs_cell_t*) * h); if (!tab) return (g1m_error_alloc); rws = malloc(sizeof(g1m_mcs_cell_t) * h * w); if (!rws) { free(tab); return (g1m_error_alloc); } /* copy */ int one_imgn = 0; g1m_bcd_t bcd; for (uint_fast32_t y = 0; y < h; y++) { /* prepare index */ tab[y] = &rws[y * w]; /* read squares */ for (uint_fast32_t x = 0; x < w; x++) { /* read the cell */ GDREAD(rawbcd, bcd) one_imgn |= g1m_bcd_frommcs(&rawbcd, &bcd); /* store it */ tab[y][x] = (g1m_mcs_cell_t){ .real = bcd, .imgn = {}, .used = 1 }; } } /* check imaginary parts */ if (one_imgn) { for (uint_fast32_t y = 0; y < h; y++) for (uint_fast32_t x = 0; x < w; x++) { GDREAD(rawbcd, bcd) if (g1m_bcd_has_special(&tab[y][x].real)) { g1m_bcd_frommcs(&rawbcd, &bcd); tab[y][x].imgn = bcd; } } } /* your sandwich, monsieur. */ handle->cells = tab; } /* no error */ return (0); /* in case of unexpected EOF */ fail: free(tab); free(rws); return (err); }