Changeset 2213


Ignore:
Timestamp:
Jan 23, 2008, 10:32:45 PM (14 years ago)
Author:
Sam Hocevar
Message:
  • img2oric now outputs Oric files.
Location:
www/labs
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • www/labs/img2oric.c

    r2212 r2213  
    3232
    3333/*
     34 * BMP output name and Oric output name
     35 */
     36#define BMPFILE "output.bmp"
     37#define ORICFILE "OUTPUT" /* ".TAP" will be appended */
     38
     39/*
    3440 * Image dimensions and recursion depth. DEPTH = 2 is a reasonable value,
    3541 * DEPTH = 3 gives good quality, and higher values may improve the results
     
    6773 * colour is repeated 6 times so that we can point to the palette to paste
    6874 * 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
    7479static const int palette[8][6 * 3] =
    7580{
    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 },
    8489};
    8590
     
    117122static inline int ctoi(int p) { return ctoi_table[p / 0x100]; }
    118123
    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 */
     127static 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;
    125133}
    126134
     
    205213    int const *voidrgb, *nvoidrgb, *vec, *rgb;
    206214    int besterror, curerror, suberror, statice, voide, nvoide;
    207     int i, c;
     215    int i, j, c;
    208216    uint8_t command, bestcommand;
    209217
     
    232240     * 33: inverse video stuff */
    233241    besterror = 0x7ffffff;
    234     bestcommand = 16;
     242    bestcommand = 0x10;
    235243    memcpy(bestrgb, voidrgb, 6 * 3 * sizeof(int));
    236     for(command = 0; command < 34; command++)
     244    for(j = 0; j < 34; j++)
    237245    {
     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
    238255        uint8_t newbg = bg, newfg = fg;
     256
     257        command = lookup[j];
    239258        domove(command, &newbg, &newfg);
    240259
    241         /* Keeping bg and fg is useless, because we could use commands
    242          * 32 and 33 instead */
    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)
    244263            continue;
    245264
     
    248267         * interesting, so we continue anyway. */
    249268
    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)
    251280        {
    252281            curerror = voide;
     
    254283            vec = voidvec;
    255284        }
    256         else if(command < 16)
     285        else if((command & 0xf8) == 0x80)
    257286        {
    258287            curerror = nvoide;
     
    260289            vec = nvoidvec;
    261290        }
    262         else if(command < 24)
     291        else if((command & 0xf8) == 0x10)
    263292        {
    264293            rgb = palette[newbg];
     
    266295            vec = tmpvec;
    267296        }
    268         else if(command < 32)
     297        else if((command & 0xf8) == 0x90)
    269298        {
    270299            rgb = palette[7 - newbg];
     
    276305            int const *bgcolor, *fgcolor;
    277306
    278             if(command == 32)
     307            if((command & 0x80) == 0x00)
    279308            {
    280309                bgcolor = palette[bg]; fgcolor = palette[fg];
     
    315344                    memcpy(tmpvec, vec2, 3 * sizeof(int));
    316345                    memcpy(tmprgb + i * 3, fgcolor, 3 * sizeof(int));
     346                    command |= (1 << (5 - i));
    317347                }
    318348            }
     
    335365        if(depth == 0)
    336366            suberror = 0; /* It’s the end of the tree */
    337         else if(command < 32)
     367        else if((command & 0x68) == 0x00)
    338368        {
    339369            bestmove(in + 6 * 3, newbg, newfg, vec, depth - 1,
     
    341371
    342372#if 0
    343             /* Penalty for background changes; they're hard to revert. The
     373            /* Slight penalty for colour changes; they're hard to revert. The
    344374             * value of 2 was determined empirically. 1.5 is not enough and
    345375             * 3 is too much. */
    346376            if(newbg != bg)
    347                 suberror *= 2;
     377                suberror = suberror * 10 / 8;
     378            else if(newfg != fg)
     379                suberror = suberror * 9 / 8;
    348380#endif
    349381        }
     
    369401{
    370402    SDL_Surface *tmp, *surface;
     403    FILE *f;
    371404    int *src, *dst, *srcl, *dstl;
    372405    uint8_t *pixels;
     
    379412    if(!tmp)
    380413        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);
    381422
    382423    init_tables();
     
    414455            int errvec[3] = { 0, 0, 0 };
    415456            int dummy, i;
    416             uint8_t move;
     457            uint8_t command;
    417458
    418459            depth = (x + DEPTH < WIDTH) ? DEPTH : (WIDTH - x) / 6 - 1;
     
    420461            dstl = dst + y * stride + x * 3;
    421462
    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);
    425466            /* Propagate error */
    426467            for(c = 0; c < 3; c++)
     
    440481            }
    441482            /* Iterate */
    442             domove(move, &bg, &fg);
     483            domove(command, &bg, &fg);
     484            /* Write byte to file */
     485            fwrite(&command, 1, 1, f);
    443486        }
    444487    }
     
    452495                pixels[y * surface->pitch + x * 4 + 2 - c]
    453496                    = itoc(dst[y * stride + x * 3 + c]) / 0x100;
    454     SDL_SaveBMP(surface, "output.bmp");
     497    SDL_SaveBMP(surface, BMPFILE);
     498
     499    fclose(f);
    455500
    456501    return 0;
  • www/labs/img2oric.html

    r2212 r2213  
    4141<h2 style="clear: both;"> Downloads </h2>
    4242
    43 <p> No downloads are available yet. However, the file <tt><a
     43<p> No real downloads are available yet. However, the file <tt><a
    4444href="img2oric.c">img2oric.c</a></tt> may be compiled on Linux to obtain an
    4545almost functional, yet extremely slow (around 2 minutes to process an image on
    4646a modern computer) program. </p>
    4747
     48<h2> Usage </h2>
     49
     50<p> <tt>img2oric</tt> will output to <tt>output.bmp</tt>, an image file
     51containing the new version, and to <tt>OUTPUT.DAT</tt> which contains the
     52Oric-format file. </p>
     53
     54<p> You can download a <a href="OUTPUT.DAT">sample <tt>OUTPUT.DAT</tt></a>
     55file as generated by <tt>img2oric</tt>. To load it into an emulator, just
     56type <b><tt>HIRES:CLOAD"OUTPUT"</tt></b> and it will be displayed on the Oric
     57screen: </p>
     58
     59<p style="text-align: center;">
     60  <img src="xeuphoric.png" width="488" height="469" class="matrix" alt="" />
     61</p>
    4862<h2> Screenshots </h2>
    4963
Note: See TracChangeset for help on using the changeset viewer.