1 /* 2 * ipdb.h 3 * Image Viewer PDB file functions. 4 * 5 * Copyright (C) 1997 Eric A. Howe 6 * 7 * This library is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU Library General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * 21 * Authors: Eric A. Howe (mu@trends.net) 22 * Bryan Henderson 2010 23 */ 24 #ifndef IPDB_H_INCLUDED 25 #define IPDB_H_INCLUDED 26 27 #include <stdio.h> 28 #include <errno.h> 29 30 /* 31 * Extra error numbers, feed these (or errno values) to ipdb_err() 32 * to get strings. 33 */ 34 #define E_BADCOLORS -1 35 #define E_NOTIMAGE -2 36 #define E_IMAGETHERE -3 37 #define E_IMAGENOTTHERE -4 38 #define E_TEXTTHERE -5 39 #define E_NOTRECHDR -6 40 #define E_UNKNOWNRECHDR -7 41 #define E_TOOBIGG -8 42 #define E_TOOBIGM -9 43 #define E_LAST -9 44 45 /* 46 * The standard pdb header. 47 */ 48 typedef struct { 49 char name[32]; /* nul terminated */ 50 uint16_t flags; /* 0 */ 51 uint16_t version; /* 0 */ 52 uint32_t ctime; /* mac time */ 53 uint32_t mtime; /* mac time */ 54 uint32_t btime; /* mac time */ 55 uint32_t mod_num; /* 0 */ 56 uint32_t app_info; /* 0 */ 57 uint32_t sort_info; /* 0 */ 58 uint8_t type[4]; /* vIMG */ 59 uint8_t id[4]; /* View */ 60 uint32_t uniq_seed; /* 0 */ 61 uint32_t next_rec; /* 0 */ 62 uint16_t num_recs; /* 1 */ 63 } PDBHEAD; 64 #define PDBHEAD_SIZE (32 + 2*2 + 6*4 + 4 + 4 + 2*4 + 2) 65 66 /* 67 * Between the pdb header and the image header we find some "mystery" bytes, 68 * these are supposed to be eight byte record headers but sometimes there 69 * are ten bytes. Version zero files use eight bytes, version 1 files appear 70 * to use ten bytes, files with attached notes (version 2?) use two sets of 71 * eight bytes. Note that this version isn't the same as the `version' field 72 * in IMAGE, that version only indicates if the file is compressed or not. 73 * 74 * The first four bytes of each piece are a four byte offset to the start 75 * of the corresponding image header or text record; the next three bytes 76 * (40 6f 80) are some kind of magic (they are always the same); the next 77 * byte is zero for image records and 1 for text records; any remaining 78 * mystery bytes (zero or two) are always zero. 79 */ 80 typedef struct { 81 uint32_t offset; /* offset, from zero, to the image */ 82 uint8_t unknown[3]; /* 40 6f 80 */ 83 uint8_t rec_type; /* byte seven, TEXT_REC || IMG_REC */ 84 size_t n_extra; /* bytes in extra */ 85 uint8_t *extra; /* extra unknown end bytes */ 86 } RECHDR; 87 #define IMG_REC (uint8_t)(0x00) 88 #define TEXT_REC (uint8_t)(0x01) 89 90 /* 91 * The image headers. 92 */ 93 typedef struct { 94 RECHDR * r; 95 96 /* 97 * Whether the image was originally compressed. Since compressed 98 * data can cross row boundaries we have to uncompress the whole 99 * thing during reads so `data' is always in the uncompressed 100 * (but packed) format. I think we can just use the `version' 101 * field for this but a little extra paranoia is worth a couple 102 * of bytes. This is also set after a write to indicate if 103 * compression was used. 104 */ 105 int compressed; 106 107 /* 108 * The actual image header, this starts at `m->offset'. 109 */ 110 char name[32]; /* nul terminated */ 111 uint8_t version; /* 0 => uncompressed, 1 => compressed */ 112 uint8_t type; /* GRAYSCALE || MONOCHROME */ 113 uint8_t reserved1[4]; /* zero */ 114 uint8_t note[4]; /* zero */ 115 uint16_t x_last; /* zero */ 116 uint16_t y_last; /* zero */ 117 uint8_t reserved2[4]; /* zero */ 118 uint16_t x_anchor; /* 0xffff */ 119 uint16_t y_anchor; /* 0xffff */ 120 uint16_t width; /* pixels (must be 0 mod 16) */ 121 uint16_t height; /* pixels */ 122 123 /* 124 * And finally, the actual image data. We always store the 125 * image data as 4 pixels per byte uncompressed. Any compression 126 * or decompression is done at I/O time. 127 */ 128 uint8_t * data; 129 } IMAGE; 130 131 #define IMAGESIZE (32 + 1 + 1 + 4 + 4 + 2*2 + 4 + 2*2 + 2*2) 132 133 /* 134 * Image types for IMAGE.type. 135 */ 136 #define IMG_GRAY16 ((uint8_t)2) 137 #define IMG_GRAY ((uint8_t)0) 138 #define IMG_MONO ((uint8_t)0xff) 139 140 const char * 141 ipdb_typeName(uint8_t const type); 142 143 144 /* 145 * Compression constants for IMAGE.version. 146 */ 147 #define IMG_COMPRESSED ((uint8_t)0x01) 148 #define IMG_UNCOMPRESSED ((uint8_t)0x00) 149 150 /* 151 * The notes record. If this exists, it will follow the image record. 152 */ 153 typedef struct { 154 RECHDR *r; 155 char *data; /* the actual text as a normal string */ 156 } TEXT; 157 158 /* 159 * One PDB file. The `t' field will be NULL if there is no note. 160 */ 161 typedef struct { 162 PDBHEAD * p; 163 IMAGE * i; 164 TEXT * t; 165 } IPDB; 166 167 /* 168 * Only use four bytes of these. 169 */ 170 #define IPDB_vIMG "vIMG" 171 #define IPDB_View "View" 172 /* 173 * Only use three bytes of this. 174 */ 175 #define IPDB_MYST "\x40\x6f\x80" 176 177 /* 178 * Flags for ipdb_write(). 179 */ 180 #define IPDB_COMPMAYBE 0 /* compress if it does any good */ 181 #define IPDB_NOCOMPRESS (1 << 1) /* don't compress */ 182 #define IPDB_COMPRESS (1 << 2) /* compress */ 183 184 #define ipdb_width(pdb) ((pdb)->i->width) 185 #define ipdb_height(pdb) ((pdb)->i->height) 186 #define ipdb_text(pdb) ((pdb)->t == NULL ? NULL : (pdb)->t->data) 187 #define ipdb_compressed(pdb) ((pdb)->i->compressed) 188 #define ipdb_ctime(pdb) ((time_t)((pdb)->p->ctime - UNIXEPOCH)) 189 #define ipdb_mtime(pdb) ((time_t)((pdb)->p->mtime - UNIXEPOCH)) 190 #define ipdb_btime(pdb) ((time_t)((pdb)->p->btime - UNIXEPOCH)) 191 #define ipdb_iname(pdb) ((pdb)->i->name) 192 #define ipdb_pname(pdb) ((pdb)->p->name) 193 #define ipdb_version(pdb) ((pdb)->i->version) 194 #define ipdb_type(pdb) ((pdb)->i->type) 195 #define ipdb_xlast(pdb) ((pdb)->i->x_last) 196 #define ipdb_ylast(pdb) ((pdb)->i->y_last) 197 #define ipdb_xanchor(pdb) ((pdb)->i->x_anchor) 198 #define ipdb_yanchor(pdb) ((pdb)->i->y_anchor) 199 200 const char * 201 ipdb_err(int error); 202 203 size_t 204 ipdb_img_size(IMAGE * const imgP); 205 206 unsigned int 207 ipdb_img_ppb(IMAGE * const imgP); 208 209 uint8_t * 210 ipdb_img_row(IMAGE * const imgP, 211 unsigned int const row); 212 213 void 214 ipdb_free(IPDB *); 215 216 IPDB * 217 ipdb_alloc(const char *); 218 219 void 220 ipdb_clear(IPDB * const pdbP); 221 222 PDBHEAD * 223 ipdb_pdbhead_alloc(const char * const name); 224 225 void 226 ipdb_pdbhead_free(PDBHEAD * const headP); 227 228 IMAGE * 229 ipdb_image_alloc(const char * const name, 230 int const type, 231 int const w, 232 int const h); 233 234 void 235 ipdb_image_free(IMAGE * const imgP); 236 237 void 238 ipdb_text_free(TEXT * const textP); 239 240 TEXT * 241 ipdb_text_alloc(const char * const content); 242 243 #endif 244