#define PIC_HEADER_WIDTH 2
#define PIC_HEADER_HEIGHT 4
+bb_map_t *blorb_map;
+
static void safe_mvaddch(int, int, int);
static struct {
static int num_pictures = 0;
-static unsigned char lookupb(unsigned char *p, int n)
-{
- return p[n];
-}
-
-
-static unsigned short lookupw(unsigned char *p, int n)
-{
- return (p[n + 1] << 8) | p[n];
-}
-
-
/*
* Do a rounding division, rounding to even if fraction part is 1/2.
* We assume x and y are nonnegative.
}
-bool unix_init_pictures (void)
-{
- FILE *file = NULL;
- int success = FALSE;
- unsigned char gheader[16];
- unsigned char *raw_info = NULL;
+extern int bigendian;
- char *filename;
- const char *basename, *dotpos;
- int namelen;
+static void swapbytes(void *object, size_t size)
+{
+ unsigned char *start, *end;
+ unsigned char swap;
+
+ if(!bigendian) {
+ for (start = (unsigned char *)object, end = start + size - 1; start < end; ++start, --end ) {
+ swap = *start;
+ *start = *end;
+ *end = swap;
+ }
+ }
+}
- if ((filename = malloc(2 * strlen(f_setup.story_name) + 10)) == NULL)
- return FALSE;
- basename = strrchr(f_setup.story_name, '/');
- if (basename) basename++; else basename = f_setup.story_name;
- dotpos = strrchr(basename, '.');
- namelen = (dotpos ? dotpos - basename : (int) strlen(basename));
- sprintf(filename, "%.*sgraphics/%.*s.mg1",
- (int)(basename - f_setup.story_name), f_setup.story_name, namelen, basename);
-
- do {
- int i, entry_size, flags, x_scale, y_scale;
-
- if (((file = fopen (filename, "rb")) == NULL)
- || (fread(&gheader, sizeof (gheader), 1, file) != 1))
- break;
-
- num_pictures = lookupw(gheader, PIC_FILE_HEADER_NUM_IMAGES);
- entry_size = lookupb(gheader, PIC_FILE_HEADER_ENTRY_SIZE);
- flags = lookupb(gheader, PIC_FILE_HEADER_FLAGS);
-
- raw_info = malloc(num_pictures * entry_size);
-
- if (fread(raw_info, num_pictures * entry_size, 1, file) != 1)
- break;
-
- pict_info = malloc((num_pictures + 1) * sizeof(*pict_info));
- pict_info[0].z_num = 0;
- pict_info[0].height = num_pictures;
- pict_info[0].width = lookupw(gheader, PIC_FILE_HEADER_VERSION);
-
- y_scale = 200;
- x_scale = (flags & 0x08) ? 640 : 320;
-
- /* Copy and scale. */
- for (i = 1; i <= num_pictures; i++) {
- unsigned char *p = raw_info + entry_size * (i - 1);
- pict_info[i].z_num = lookupw(p, PIC_HEADER_NUMBER);
- pict_info[i].orig_height = lookupw(p, PIC_HEADER_HEIGHT);
- pict_info[i].orig_width = lookupw(p, PIC_HEADER_WIDTH);
-
- pict_info[i].height = round_div(pict_info[i].orig_height *
- h_screen_rows, y_scale);
- pict_info[i].width = round_div(pict_info[i].orig_width *
- h_screen_cols, x_scale);
-
- /* Don't let dimensions get rounded to nothing. */
- if (pict_info[i].orig_height && !pict_info[i].height)
- pict_info[1].height = 1;
- if (pict_info[i].orig_width && !pict_info[i].width)
- pict_info[i].width = 1;
+bool unix_init_pictures (void)
+{
+ int maxlegalpic = 0;
+ int i, x_scale, y_scale;
+ bool success = FALSE;
+
+ unsigned char png_magic[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
+ unsigned char ihdr_name[] = "IHDR";
+ unsigned char jpg_magic[3] = {0xFF, 0xD8, 0xFF};
+ unsigned char jfif_name[5] = {'J', 'F', 'I', 'F', 0x00};
+
+ bb_result_t res;
+
+ uint32 pos;
+
+ if (blorb_map == NULL) return FALSE;
+
+ bb_count_resources(blorb_map, bb_ID_Pict, &num_pictures, NULL, &maxlegalpic);
+ pict_info = malloc((num_pictures + 1) * sizeof(*pict_info));
+ pict_info[0].z_num = 0;
+ pict_info[0].height = num_pictures;
+ pict_info[0].width = bb_get_release_num(blorb_map);
+
+ y_scale = 200;
+ x_scale = 320;
+
+ for (i = 1; i <= num_pictures; i++) {
+ if (bb_load_resource(blorb_map, bb_method_Memory, &res, bb_ID_Pict, i) == bb_err_None) {
+ /* Copy and scale. */
+ pict_info[i].z_num = i;
+ /* Check to see if we're dealing with a PNG file. */
+ if (memcmp(res.data.ptr, png_magic, 8) == 0) {
+ /* Check for IHDR chunk. If it's not there, PNG file is invalid. */
+ if (memcmp(res.data.ptr+12, ihdr_name, 4) == 0) {
+ pict_info[i].orig_width =
+ (*((unsigned char *)res.data.ptr+16) << 24) +
+ (*((unsigned char *)res.data.ptr+17) << 16) +
+ (*((unsigned char *)res.data.ptr+18) << 8) +
+ (*((unsigned char *)res.data.ptr+19) << 0);
+ pict_info[i].orig_height =
+ (*((unsigned char *)res.data.ptr+20) << 24) +
+ (*((unsigned char *)res.data.ptr+21) << 16) +
+ (*((unsigned char *)res.data.ptr+22) << 8) +
+ (*((unsigned char *)res.data.ptr+23) << 0);
+ }
+ } else if (memcmp(res.data.ptr, jpg_magic, 3) == 0) { /* Is it JPEG? */
+ if (memcmp(res.data.ptr+6, jfif_name, 5) == 0) { /* Look for JFIF */
+ pos = 11;
+ while (pos < res.length) {
+ pos++;
+ if (pos >= res.length) break; /* Avoid segfault */
+ if (*((unsigned char *)res.data.ptr+pos) != 0xFF) continue;
+ if (*((unsigned char *)res.data.ptr+pos+1) != 0xC0) continue;
+ pict_info[i].orig_width =
+ (*((unsigned char *)res.data.ptr+pos+7)*256) +
+ *((unsigned char *)res.data.ptr+pos+8);
+ pict_info[i].orig_height =
+ (*((unsigned char *)res.data.ptr+pos+5)*256) +
+ *((unsigned char *)res.data.ptr+pos+6);
+ } /* while */
+ } /* JFIF */
+ } /* JPEG */
+ }
+ if (bigendian) {
+ swapbytes(&pict_info[i].orig_width, 4);
+ swapbytes(&pict_info[i].orig_height, 4);
}
+ pict_info[i].height = round_div(pict_info[i].orig_height *
+ h_screen_rows, y_scale);
+ pict_info[i].width = round_div(pict_info[i].orig_width *
+ h_screen_cols, x_scale);
+
+ /* Don't let dimensions get rounded to nothing. */
+ if (pict_info[i].orig_height && !pict_info[i].height)
+ pict_info[1].height = 1;
+ if (pict_info[i].orig_width && !pict_info[i].width)
+ pict_info[i].width = 1;
+
success = TRUE;
- } while (0);
- if (file)
- fclose(file);
- if (raw_info)
- free(raw_info);
+ } /* for */
return success;
}