summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/face2png.c88
1 files changed, 62 insertions, 26 deletions
diff --git a/utils/face2png.c b/utils/face2png.c
index a9a7c29..a25b5dc 100644
--- a/utils/face2png.c
+++ b/utils/face2png.c
@@ -19,6 +19,16 @@
#include <stdlib.h>
#include <stdint.h>
+uint16_t
+getint16BE(FILE *f)
+{
+ uint16_t n;
+ n = fgetc(f) << 8;
+ n |= fgetc(f);
+
+ return n;
+}
+
uint32_t
getint32BE(FILE *f)
{
@@ -88,6 +98,40 @@ printpng(uint16_t **pixels, int height, int width)
png_destroy_write_struct(&png_ptr, &info_ptr);
}
+/*
+ * read a face from offset in f and store it into pixels.
+ */
+void
+getface(FILE *f, long offset, int height, int width, uint16_t **pixels)
+{
+ /*
+ * In the original format, on every other line, every other pair of
+ * pixels is swapped. Here we transpose it into top-bottom left-right.
+ */
+ uint16_t q[4];
+ int x, y;
+
+ fseek(f, offset, SEEK_SET);
+
+ for (y = 0; y < height; ++y) {
+ for (x = 0; x < width; ++x) {
+ if (y % 2 == 0) {
+ pixels[x][y] = fgetc(f) << 8;
+ pixels[x][y] |= fgetc(f);
+ } else {
+ q[x % 4] = fgetc(f) << 8;
+ q[x % 4] |= fgetc(f);
+ if (x % 4 == 3) {
+ pixels[x - 3][y] = q[2];
+ pixels[x - 2][y] = q[3];
+ pixels[x - 1][y] = q[0];
+ pixels[x][y] = q[1];
+ }
+ }
+ }
+ }
+}
+
int
main(int argc, char *argv[])
{
@@ -97,6 +141,7 @@ main(int argc, char *argv[])
int height, width;
uint32_t nfaces;
uint32_t *offsets;
+ uint16_t *heights, *widths;
if (argc != 2) {
errx(1, "Usage: face2png file");
@@ -107,20 +152,32 @@ main(int argc, char *argv[])
err(1, "Could not open file '%s'", argv[1]);
}
- height = 64;
- width = 64;
-
nfaces = getint32BE(f);
offsets = reallocarray(NULL, nfaces, sizeof *offsets);
+ heights = reallocarray(NULL, nfaces, sizeof *heights);
+ widths = reallocarray(NULL, nfaces, sizeof *widths);
+ if (offsets == NULL || heights == NULL || widths == NULL) {
+ err(1, "Could not allocate memory");
+ }
for (y = 0; y < nfaces; ++y) {
offsets[y] = getint32BE(f);
}
for (y = 0; y < nfaces; ++y) {
+ fseek(f, offsets[y] - 8, SEEK_SET);
+
+ /*
+ * XXX
+ * check whether height follows width or width follows height
+ */
+ heights[y] = getint16BE(f);
+ widths[y] = getint16BE(f);
+
getint32BE(f);
}
- fseek(f, offsets[nfaces - 1], SEEK_SET);
+ height = heights[nfaces - 1];
+ width = widths[nfaces - 1];
pixels = reallocarray(NULL, width, sizeof *pixels);
if (pixels == NULL) {
@@ -134,28 +191,7 @@ main(int argc, char *argv[])
}
}
- /*
- * In the original format, on every other line, every other pair of
- * pixels is swapped. Here we transpose it into top-bottom left-right.
- */
- uint16_t q[4];
- for (y = 0; y < height; ++y) {
- for (x = 0; x < width; ++x) {
- if (y % 2 == 0) {
- pixels[x][y] = fgetc(f) << 8;
- pixels[x][y] |= fgetc(f);
- } else {
- q[x % 4] = fgetc(f) << 8;
- q[x % 4] |= fgetc(f);
- if (x % 4 == 3) {
- pixels[x - 3][y] = q[2];
- pixels[x - 2][y] = q[3];
- pixels[x - 1][y] = q[0];
- pixels[x][y] = q[1];
- }
- }
- }
- }
+ getface(f, offsets[nfaces - 1], height, width, pixels);
printpng(pixels, height, width);