Skip to content

Commit

Permalink
Merge pull request #127 from saxbophone/develop
Browse files Browse the repository at this point in the history
v0.21.0 - Render Backends Refactor
  • Loading branch information
saxbophone authored Nov 1, 2016
2 parents 7444fb7 + d5d46b2 commit f72532b
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 11 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# begin basic metadata
cmake_minimum_required(VERSION 3.0)

project(libsaxbospiral VERSION 0.20.1 LANGUAGES C)
project(libsaxbospiral VERSION 0.21.0 LANGUAGES C)

# set default C standard to use (C99)
set(SAXBOSPIRAL_C_STANDARD "99")
Expand Down
38 changes: 37 additions & 1 deletion saxbospiral/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ static void get_bounds(sxbp_spiral_t spiral, sxbp_co_ord_t* bounds) {
* - That image->pixels is NULL
* - That spiral.lines is not NULL
*/
sxbp_status_t sxbp_render_spiral(sxbp_spiral_t spiral, sxbp_bitmap_t* image) {
sxbp_status_t sxbp_render_spiral_raw(
sxbp_spiral_t spiral, sxbp_bitmap_t* image
) {
// preconditional assertions
assert(image->pixels == NULL);
assert(spiral.lines != NULL);
Expand Down Expand Up @@ -159,6 +161,40 @@ sxbp_status_t sxbp_render_spiral(sxbp_spiral_t spiral, sxbp_bitmap_t* image) {
return result;
}

/*
* given a spiral struct, a pointer to a blank buffer and a pointer to a
* function with the appropriate signature, render the spiral as a bitmap and
* then call the pointed-to function to render the image to the buffer (in
* whatever format the function pointer is written for)
* returns a status struct with error information (if any)
*
* Asserts:
* - That spiral.lines is not NULL
* - That buffer->bytes is NULL
* - That the function pointer is not NULL
*/
sxbp_status_t sxbp_render_spiral_image(
sxbp_spiral_t spiral, sxbp_buffer_t* buffer,
sxbp_status_t(* image_writer_callback)(
sxbp_bitmap_t image, sxbp_buffer_t* buffer
)
) {
// preconditional assertions
assert(spiral.lines != NULL);
assert(buffer->bytes == NULL);
assert(image_writer_callback != NULL);
// create bitmap to render raw image to
sxbp_bitmap_t raw_image = {0, 0, NULL};
// render spiral to raw image (and store success/failure)
sxbp_status_t result = sxbp_render_spiral_raw(spiral, &raw_image);
// check return status
if(result != SXBP_OPERATION_OK) {
return result;
}
// render to buffer using callback (and return its status code)
return image_writer_callback(raw_image, buffer);
}

#ifdef __cplusplus
} // extern "C"
#endif
23 changes: 22 additions & 1 deletion saxbospiral/render.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,28 @@ typedef struct sxbp_bitmap_t {
* - That image->pixels is NULL
* - That spiral.lines is not NULL
*/
sxbp_status_t sxbp_render_spiral(sxbp_spiral_t spiral, sxbp_bitmap_t* image);
sxbp_status_t sxbp_render_spiral_raw(
sxbp_spiral_t spiral, sxbp_bitmap_t* image
);

/*
* given a spiral struct, a pointer to a blank buffer and a pointer to a
* function with the appropriate signature, render the spiral as a bitmap and
* then call the pointed-to function to render the image to the buffer (in
* whatever format the function pointer is written for)
* returns a status struct with error information (if any)
*
* Asserts:
* - That spiral.lines is not NULL
* - That buffer->bytes is NULL
* - That the function pointer is not NULL
*/
sxbp_status_t sxbp_render_spiral_image(
sxbp_spiral_t spiral, sxbp_buffer_t* buffer,
sxbp_status_t(* image_writer_callback)(
sxbp_bitmap_t image, sxbp_buffer_t* buffer
)
);

#ifdef __cplusplus
} // extern "C"
Expand Down
133 changes: 133 additions & 0 deletions saxbospiral/render_backends/backend_pbm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* This source file forms part of libsaxbospiral, a library which generates
* experimental 2D spiral-like shapes based on input binary data.
*
* This compilation unit provides functionality to render a bitmap struct to a
* PBM image (binary version, stored in a buffer).
*
* Reference materials used for the PBM format are located at
* <http://netpbm.sourceforge.net/doc/pbm.html>
*
*
*
* Copyright (C) 2016, Joshua Saxby joshua.a.saxby+TNOPLuc8vM==@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License (version 3),
* as published by the Free Software Foundation.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <inttypes.h>
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../saxbospiral.h"
#include "../render.h"
#include "backend_pbm.h"


#ifdef __cplusplus
extern "C"{
#endif

/*
* given a bitmap_t struct and a pointer to a blank buffer_t, write the bitmap
* data as a PBM image to the buffer
* returns a status struct containing error information, if any
*
* Asserts:
* - That bitmap.pixels is not NULL
* - That buffer->bytes is NULL
*/
sxbp_status_t sxbp_render_backend_pbm(
sxbp_bitmap_t bitmap, sxbp_buffer_t* buffer
) {
// preconditional assertsions
assert(bitmap.pixels != NULL);
assert(buffer->bytes == NULL);
/*
* allocate two char arrays for the width and height strings - these may be
* up to 19 characters each (max uint64_t is 19 digits long), so allocate 2
* char arrays of 20 chars each (1 extra char for null-terminator)
*/
char width_string[20], height_string[20];
// these are used to keep track of how many digits each is
int width_string_length, height_string_length = 0;
// convert width and height to a decimal string, store lengths
width_string_length = sprintf(width_string, "%" PRIu64, bitmap.width);
height_string_length = sprintf(height_string, "%" PRIu64, bitmap.height);
/*
* now that we know the length of the image dimension strings, we can now
* calculate how much memory we'll have to allocate for the image buffer
*/
// calculate number of bytes per row - this is ceiling(width / 8)
size_t bytes_per_row = (size_t)ceil((double)bitmap.width / 8.0);
// calculate number of bytes for the entire image pixels (rows and columns)
size_t image_bytes = bytes_per_row * bitmap.height;
// finally put it all together to get total image buffer size
size_t image_buffer_size = (
3 // "P4" magic number + whitespace
+ width_string_length + 1 // width of image in decimal + whitespace
+ height_string_length + 1 // height of image in decimal + whitespace
+ image_bytes // lastly, the bytes which make up the image pixels
);
// try and allocate the data for the buffer
buffer->bytes = calloc(image_buffer_size, sizeof(uint8_t));
// check fo memory allocation failure
if(buffer->bytes == NULL) {
return SXBP_MALLOC_REFUSED;
} else {
// set buffer size
buffer->size = image_buffer_size;
// otherwise carry on
size_t index = 0; // this index is used to index the buffer
// construct magic number + whitespace
memcpy(buffer->bytes + index, "P4\n", 3);
index += 3;
// image width
memcpy(buffer->bytes + index, width_string, width_string_length);
index += width_string_length;
// whitespace
memcpy(buffer->bytes + index, "\n", 1);
index += 1;
// image height
memcpy(buffer->bytes + index, height_string, height_string_length);
index += height_string_length;
// whitespace
memcpy(buffer->bytes + index, "\n", 1);
index += 1;
// now for the image data, packed into rows to the nearest byte
for(size_t y = 0; y < bitmap.height; y++) { // row loop
for(size_t x = 0; x < bitmap.width; x++) {
// byte index is index + floor(x / 8)
size_t byte_index = index + (x / 8);
// bit index is x mod 8
uint8_t bit_index = x % 8;
// write bits most-significant-bit first
buffer->bytes[byte_index] |= (
// black pixel = bool true = 1, just like in PBM format
bitmap.pixels[x][y] << (7 - bit_index)
);
}
// increment index so next row is written in the correct place
index += bytes_per_row;
}
return SXBP_OPERATION_OK;
}
}

#ifdef __cplusplus
} // extern "C"
#endif
56 changes: 56 additions & 0 deletions saxbospiral/render_backends/backend_pbm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* This source file forms part of libsaxbospiral, a library which generates
* experimental 2D spiral-like shapes based on input binary data.
*
* This compilation unit provides functionality to render a bitmap struct to a
* PBM image (binary version, stored in a buffer).
*
* Reference materials used for the PBM format are located at
* <http://netpbm.sourceforge.net/doc/pbm.html>
*
*
*
* Copyright (C) 2016, Joshua Saxby joshua.a.saxby+TNOPLuc8vM==@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License (version 3),
* as published by the Free Software Foundation.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SAXBOPHONE_SAXBOSPIRAL_BACKEND_PBM_H
#define SAXBOPHONE_SAXBOSPIRAL_BACKEND_PBM_H

#include "../saxbospiral.h"
#include "../render.h"


#ifdef __cplusplus
extern "C"{
#endif

/*
* given a bitmap_t struct and a pointer to a blank buffer_t, write the bitmap
* data as a PBM image to the buffer
* returns a status struct containing error information, if any
*
* Asserts:
* - That bitmap.pixels is not NULL
* - That buffer->bytes is NULL
*/
sxbp_status_t sxbp_render_backend_pbm(
sxbp_bitmap_t bitmap, sxbp_buffer_t* buffer
);

#ifdef __cplusplus
} // extern "C"
#endif

// end of header file
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* This source file forms part of libsaxbospiral, a library which generates
* experimental 2D spiral-like shapes based on input binary data.
*
* This compilation unit provides functionality to render a bitmap struct to PNG
* This compilation unit provides functionality to render a bitmap struct to a
* PNG image (stored in a buffer).
*
*
*
Expand All @@ -28,7 +29,7 @@

#include "../saxbospiral.h"
#include "../render.h"
#include "png_backend.h"
#include "backend_png.h"


#ifdef __cplusplus
Expand Down Expand Up @@ -89,7 +90,7 @@ static void cleanup_png_lib(
* - That bitmap.pixels is not NULL
* - That buffer->bytes is NULL
*/
sxbp_status_t sxbp_write_png_image(
sxbp_status_t sxbp_render_backend_png(
sxbp_bitmap_t bitmap, sxbp_buffer_t* buffer
) {
// preconditional assertsions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* This source file forms part of libsaxbospiral, a library which generates
* experimental 2D spiral-like shapes based on input binary data.
*
* This compilation unit provides functionality to render a bitmap struct to PNG
* This compilation unit provides functionality to render a bitmap struct to a
* PNG image (stored in a buffer).
*
*
*
Expand All @@ -20,8 +21,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SAXBOPHONE_SAXBOSPIRAL_PNG_BACKEND_H
#define SAXBOPHONE_SAXBOSPIRAL_PNG_BACKEND_H
#ifndef SAXBOPHONE_SAXBOSPIRAL_BACKEND_PNG_H
#define SAXBOPHONE_SAXBOSPIRAL_BACKEND_PNG_H

#include "../saxbospiral.h"
#include "../render.h"
Expand All @@ -40,7 +41,9 @@ extern "C"{
* - That bitmap.pixels is not NULL
* - That buffer->bytes is NULL
*/
sxbp_status_t sxbp_write_png_image(sxbp_bitmap_t bitmap, sxbp_buffer_t* buffer);
sxbp_status_t sxbp_render_backend_png(
sxbp_bitmap_t bitmap, sxbp_buffer_t* buffer
);

#ifdef __cplusplus
} // extern "C"
Expand Down
1 change: 0 additions & 1 deletion saxbospiral/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#include "saxbospiral.h"
#include "plot.h"
Expand Down

0 comments on commit f72532b

Please sign in to comment.