- Timestamp:
- Jan 23, 2008, 10:32:45 PM (15 years ago)
- Location:
- www/labs
- Files:
-
- 2 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
www/labs/img2oric.c
r2212 r2213 32 32 33 33 /* 34 * BMP output name and Oric output name 35 */ 36 #define BMPFILE "output.bmp" 37 #define ORICFILE "OUTPUT" /* ".TAP" will be appended */ 38 39 /* 34 40 * Image dimensions and recursion depth. DEPTH = 2 is a reasonable value, 35 41 * DEPTH = 3 gives good quality, and higher values may improve the results … … 67 73 * colour is repeated 6 times so that we can point to the palette to paste 68 74 * whole blocks of 6 pixels. It’s also organised so that palette[7-x] is the 69 * RGB negative of palette[x]. Finally, it’s roughly ordered by brightness to 70 * allow for other tricks later. 71 */ 72 #define O 0x0000 73 #define I 0xffff 75 * RGB negative of palette[x], and screen command X uses palette[X & 7]. 76 */ 77 #define o 0x0000 78 #define X 0xffff 74 79 static const int palette[8][6 * 3] = 75 80 { 76 { O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O},77 { O, O, I, O, O, I, O, O, I, O, O, I, O, O, I, O, O, I},78 { I, O, O, I, O, O, I, O, O, I, O, O, I, O, O, I, O, O},79 { I, O, I, I, O, I, I, O, I, I, O, I, I, O, I, I, O, I},80 { O, I, O, O, I, O, O, I, O, O, I, O, O, I, O, O, I, O},81 { O, I, I, O, I, I, O, I, I, O, I, I, O, I, I, O, I, I},82 { I, I, O, I, I, O, I, I, O, I, I, O, I, I, O, I, I, O},83 { I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I},81 { o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o }, 82 { X, o, o, X, o, o, X, o, o, X, o, o, X, o, o, X, o, o }, 83 { o, X, o, o, X, o, o, X, o, o, X, o, o, X, o, o, X, o }, 84 { X, X, o, X, X, o, X, X, o, X, X, o, X, X, o, X, X, o }, 85 { o, o, X, o, o, X, o, o, X, o, o, X, o, o, X, o, o, X }, 86 { X, o, X, X, o, X, X, o, X, X, o, X, X, o, X, X, o, X }, 87 { o, X, X, o, X, X, o, X, X, o, X, X, o, X, X, o, X, X }, 88 { X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X }, 84 89 }; 85 90 … … 117 122 static inline int ctoi(int p) { return ctoi_table[p / 0x100]; } 118 123 119 static inline void domove(uint8_t move, uint8_t *bg, uint8_t *fg) 120 { 121 if(move < 16) 122 *fg = move & 0x7; 123 else if(move < 32) 124 *bg = move & 0x7; 124 /* 125 * Set new background and foreground colours according to the given command. 126 */ 127 static inline void domove(uint8_t command, uint8_t *bg, uint8_t *fg) 128 { 129 if((command & 0x78) == 0x00) 130 *fg = command & 0x7; 131 else if((command & 0x78) == 0x10) 132 *bg = command & 0x7; 125 133 } 126 134 … … 205 213 int const *voidrgb, *nvoidrgb, *vec, *rgb; 206 214 int besterror, curerror, suberror, statice, voide, nvoide; 207 int i, c;215 int i, j, c; 208 216 uint8_t command, bestcommand; 209 217 … … 232 240 * 33: inverse video stuff */ 233 241 besterror = 0x7ffffff; 234 bestcommand = 16;242 bestcommand = 0x10; 235 243 memcpy(bestrgb, voidrgb, 6 * 3 * sizeof(int)); 236 for( command = 0; command < 34; command++)244 for(j = 0; j < 34; j++) 237 245 { 246 static uint8_t const lookup[] = 247 { 248 0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07, 249 0x80, 0x84, 0x81, 0x85, 0x82, 0x86, 0x83, 0x87, 250 0x10, 0x14, 0x11, 0x15, 0x12, 0x16, 0x13, 0x17, 251 0x90, 0x94, 0x91, 0x95, 0x92, 0x96, 0x93, 0x97, 252 0x40, 0xc0 253 }; 254 238 255 uint8_t newbg = bg, newfg = fg; 256 257 command = lookup[j]; 239 258 domove(command, &newbg, &newfg); 240 259 241 /* Keeping bg and fg is useless, because we could use commands242 * 32 and 33instead */243 if( command < 32&& newbg == bg && newfg == fg)260 /* Keeping bg and fg is useless, because we could use standard 261 * pixel printing instead */ 262 if((command & 0x40) == 0x00 && newbg == bg && newfg == fg) 244 263 continue; 245 264 … … 248 267 * interesting, so we continue anyway. */ 249 268 250 if(command < 8) 269 #if 0 270 /* Bit 6 off and bit 5 on seems illegal */ 271 if((command & 0x60) == 0x20) 272 continue; 273 274 /* Bits 6 and 5 off and bit 3 on seems illegal */ 275 if((command & 0x68) == 0x08) 276 continue; 277 #endif 278 279 if((command & 0xf8) == 0x00) 251 280 { 252 281 curerror = voide; … … 254 283 vec = voidvec; 255 284 } 256 else if( command < 16)285 else if((command & 0xf8) == 0x80) 257 286 { 258 287 curerror = nvoide; … … 260 289 vec = nvoidvec; 261 290 } 262 else if( command < 24)291 else if((command & 0xf8) == 0x10) 263 292 { 264 293 rgb = palette[newbg]; … … 266 295 vec = tmpvec; 267 296 } 268 else if( command < 32)297 else if((command & 0xf8) == 0x90) 269 298 { 270 299 rgb = palette[7 - newbg]; … … 276 305 int const *bgcolor, *fgcolor; 277 306 278 if( command == 32)307 if((command & 0x80) == 0x00) 279 308 { 280 309 bgcolor = palette[bg]; fgcolor = palette[fg]; … … 315 344 memcpy(tmpvec, vec2, 3 * sizeof(int)); 316 345 memcpy(tmprgb + i * 3, fgcolor, 3 * sizeof(int)); 346 command |= (1 << (5 - i)); 317 347 } 318 348 } … … 335 365 if(depth == 0) 336 366 suberror = 0; /* It’s the end of the tree */ 337 else if( command < 32)367 else if((command & 0x68) == 0x00) 338 368 { 339 369 bestmove(in + 6 * 3, newbg, newfg, vec, depth - 1, … … 341 371 342 372 #if 0 343 /* Penalty for backgroundchanges; they're hard to revert. The373 /* Slight penalty for colour changes; they're hard to revert. The 344 374 * value of 2 was determined empirically. 1.5 is not enough and 345 375 * 3 is too much. */ 346 376 if(newbg != bg) 347 suberror *= 2; 377 suberror = suberror * 10 / 8; 378 else if(newfg != fg) 379 suberror = suberror * 9 / 8; 348 380 #endif 349 381 } … … 369 401 { 370 402 SDL_Surface *tmp, *surface; 403 FILE *f; 371 404 int *src, *dst, *srcl, *dstl; 372 405 uint8_t *pixels; … … 379 412 if(!tmp) 380 413 return 2; 414 415 f = fopen(ORICFILE ".TAP", "w"); 416 if(!f) 417 return 3; 418 fwrite("\x16\x16\x16\x16\x24", 1, 5, f); 419 fwrite("\x00\xff\x80\x00\xbf\x3f\xa0\x00", 1, 8, f); 420 fwrite(ORICFILE, 1, strlen(ORICFILE), f); 421 fwrite("\x00", 1, 1, f); 381 422 382 423 init_tables(); … … 414 455 int errvec[3] = { 0, 0, 0 }; 415 456 int dummy, i; 416 uint8_t move;457 uint8_t command; 417 458 418 459 depth = (x + DEPTH < WIDTH) ? DEPTH : (WIDTH - x) / 6 - 1; … … 420 461 dstl = dst + y * stride + x * 3; 421 462 422 /* Recursively compute and apply best move*/423 move= bestmove(srcl, bg, fg, errvec, depth, 0x7fffff,424 &dummy, dstl);463 /* Recursively compute and apply best command */ 464 command = bestmove(srcl, bg, fg, errvec, depth, 0x7fffff, 465 &dummy, dstl); 425 466 /* Propagate error */ 426 467 for(c = 0; c < 3; c++) … … 440 481 } 441 482 /* Iterate */ 442 domove(move, &bg, &fg); 483 domove(command, &bg, &fg); 484 /* Write byte to file */ 485 fwrite(&command, 1, 1, f); 443 486 } 444 487 } … … 452 495 pixels[y * surface->pitch + x * 4 + 2 - c] 453 496 = itoc(dst[y * stride + x * 3 + c]) / 0x100; 454 SDL_SaveBMP(surface, "output.bmp"); 497 SDL_SaveBMP(surface, BMPFILE); 498 499 fclose(f); 455 500 456 501 return 0; -
www/labs/img2oric.html
r2212 r2213 41 41 <h2 style="clear: both;"> Downloads </h2> 42 42 43 <p> No downloads are available yet. However, the file <tt><a43 <p> No real downloads are available yet. However, the file <tt><a 44 44 href="img2oric.c">img2oric.c</a></tt> may be compiled on Linux to obtain an 45 45 almost functional, yet extremely slow (around 2 minutes to process an image on 46 46 a modern computer) program. </p> 47 47 48 <h2> Usage </h2> 49 50 <p> <tt>img2oric</tt> will output to <tt>output.bmp</tt>, an image file 51 containing the new version, and to <tt>OUTPUT.DAT</tt> which contains the 52 Oric-format file. </p> 53 54 <p> You can download a <a href="OUTPUT.DAT">sample <tt>OUTPUT.DAT</tt></a> 55 file as generated by <tt>img2oric</tt>. To load it into an emulator, just 56 type <b><tt>HIRES:CLOAD"OUTPUT"</tt></b> and it will be displayed on the Oric 57 screen: </p> 58 59 <p style="text-align: center;"> 60 <img src="xeuphoric.png" width="488" height="469" class="matrix" alt="" /> 61 </p> 48 62 <h2> Screenshots </h2> 49 63
Note: See TracChangeset
for help on using the changeset viewer.