Changeset 1283 for libcaca


Ignore:
Timestamp:
Nov 5, 2006, 11:20:51 PM (14 years ago)
Author:
Sam Hocevar
Message:
  • Updated the caca export format so that it supports multiple frames.
  • Updated the caca importer to reflect that; only one frame is read at the moment.
  • Added an "utf8cr" export format for UTF-8 + CRLF exports.
  • Updated cacaserver to reflect file format changes.
Location:
libcaca/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/cucul/export.c

    r1266 r1283  
    3232#include "cucul_internals.h"
    3333
     34static inline int sprintu32(char *s, uint32_t x)
     35{
     36    s[0] = (uint8_t)(x >> 24);
     37    s[1] = (uint8_t)(x >> 16) & 0xff;
     38    s[2] = (uint8_t)(x >>  8) & 0xff;
     39    s[3] = (uint8_t)(x      ) & 0xff;
     40    return 4;
     41}
     42
     43static inline int sprintu16(char *s, uint16_t x)
     44{
     45    s[0] = (uint8_t)(x >>  8) & 0xff;
     46    s[1] = (uint8_t)(x      ) & 0xff;
     47    return 2;
     48}
     49
    3450static int export_caca(cucul_canvas_t *, cucul_buffer_t *);
    3551static int export_ansi(cucul_canvas_t *, cucul_buffer_t *);
    36 static int export_utf8(cucul_canvas_t *, cucul_buffer_t *);
     52static int export_utf8(cucul_canvas_t *, cucul_buffer_t *, int);
    3753static int export_html(cucul_canvas_t *, cucul_buffer_t *);
    3854static int export_html3(cucul_canvas_t *, cucul_buffer_t *);
     
    91107        ret = export_ansi(cv, ex);
    92108    else if(!strcasecmp("utf8", format))
    93         ret = export_utf8(cv, ex);
     109        ret = export_utf8(cv, ex, 0);
     110    else if(!strcasecmp("utf8cr", format))
     111        ret = export_utf8(cv, ex, 1);
    94112    else if(!strcasecmp("html", format))
    95113        ret = export_html(cv, ex);
     
    135153        "ansi", "ANSI",
    136154        "utf8", "UTF-8 with ANSI escape codes",
     155        "utf8cr", "UTF-8 with ANSI escape codes and MS-DOS \\r",
    137156        "html", "HTML",
    138157        "html3", "backwards-compatible HTML",
     
    157176    uint32_t *chars = cv->chars;
    158177    char *cur;
    159     uint32_t w, h;
    160178    unsigned int n;
    161179
    162     /* 16 bytes for the canvas, 8 bytes for each character cell. */
    163     ex->size = 16 + 8 * cv->width * cv->height;
     180    /* 44 bytes for the header:
     181     *  - 4 bytes for "\xCA\xCA" + "CV"
     182     *  - 16 bytes for the canvas header
     183     *  - 24 bytes for the frame info
     184     * 8 bytes for each character cell */
     185    ex->size = 44 + 8 * cv->width * cv->height;
    164186    ex->data = malloc(ex->size);
    165187
    166188    cur = ex->data;
    167189
    168     w = cv->width;
    169     h = cv->height;
    170 
    171     cur += sprintf(cur, "CACACANV%c%c%c%c%c%c%c%c",
    172                    (unsigned char)(w >> 24), (unsigned char)((w >> 16) & 0xff),
    173                    (unsigned char)((w >> 8) & 0xff), (unsigned char)(w & 0xff),
    174                    (unsigned char)(h >> 24), (unsigned char)((h >> 16) & 0xff),
    175                    (unsigned char)((h >> 8) & 0xff), (unsigned char)(h & 0xff));
    176 
     190    /* magic */
     191    cur += sprintf(cur, "%s", "\xCA\xCA" "CV");
     192
     193    /* canvas_header */
     194    cur += sprintu32(cur, 16 + 24);
     195    cur += sprintu32(cur, cv->width * cv->height * 8);
     196    cur += sprintu16(cur, 0x0001);
     197    cur += sprintu32(cur, 1);
     198    cur += sprintu16(cur, 0x0000);
     199
     200    /* frame_info */
     201    cur += sprintu32(cur, cv->width);
     202    cur += sprintu32(cur, cv->height);
     203    cur += sprintu32(cur, 0);
     204    cur += sprintu32(cur, cv->curattr);
     205    cur += sprintu32(cur, 0);
     206    cur += sprintu32(cur, 0);
     207
     208    /* canvas_data */
    177209    for(n = cv->height * cv->width; n--; )
    178210    {
    179         uint32_t ch = *chars++;
    180         uint32_t a = *attrs++;
    181 
    182         *cur++ = ch >> 24;
    183         *cur++ = (ch >> 16) & 0xff;
    184         *cur++ = (ch >> 8) & 0xff;
    185         *cur++ = ch & 0xff;
    186 
    187         *cur++ = a >> 24;
    188         *cur++ = (a >> 16) & 0xff;
    189         *cur++ = (a >> 8) & 0xff;
    190         *cur++ = a & 0xff;
     211        cur += sprintu32(cur, *chars++);
     212        cur += sprintu32(cur, *attrs++);
    191213    }
    192214
     
    194216}
    195217
     218/*
     219 * The libcaca canvas format, version 1
     220 * ------------------------------------
     221 *
     222 * All types are big endian.
     223 *
     224 * struct
     225 * {
     226 * magic:
     227 *    uint8_t caca_header[2];    // "\xCA\xCA"
     228 *    uint8_t caca_file_type[2]; // "CV"
     229 *
     230 * canvas_header:
     231 *    uint32_t control_size;     // Control size (canvas_data - canvas_header)
     232 *    uint32_t data_size;        // Data size (EOF - canvas_data)
     233 *
     234 *    uint16_t version;          // Canvas format version
     235 *                               //  bit 0: set to 1 if canvas is compatible
     236 *                               //         with version 1 of the format
     237 *                               //  bits 1-15: unused yet, must be 0
     238 *
     239 *    uint32_t frames;           // Frame count
     240 *
     241 *    uint16_t flags;            // Feature flags
     242 *                               //  bits 0-15: unused yet, must be 0
     243 *
     244 * frame_info:
     245 *    struct
     246 *    {
     247 *       uint32_t width;         // Frame width
     248 *       uint32_t height;        // Frame height
     249 *       uint32_t duration;      // Frame duration in milliseconds, 0 to
     250 *                               // not specify a duration
     251 *       uint32_t attr;          // Graphics context attribute
     252 *       int32_t handle_x;       // Handle X coordinate
     253 *       int32_t handle_y;       // Handle Y coordinate
     254 *    }
     255 *    frame_list[frames];
     256 *
     257 * control_extension_1:
     258 * control_extension_2:
     259 *    ...
     260 * control_extension_N:
     261 *    ...                        // reserved for future use
     262 *
     263 * canvas_data:
     264 *    uint8_t data[data_size];   // canvas data
     265 *
     266 * data_extension_1:
     267 * data_extension_2:
     268 *    ...
     269 * data_extension_N:
     270 *    ...                        // reserved for future use
     271 * };
     272 */
     273
    196274/* Generate UTF-8 representation of current canvas. */
    197 static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex)
     275static int export_utf8(cucul_canvas_t *cv, cucul_buffer_t *ex, int cr)
    198276{
    199277    static uint8_t const palette[] =
     
    263341            cur += sprintf(cur, "\033[0m");
    264342
    265         cur += sprintf(cur, "\n");
     343        cur += sprintf(cur, cr ? "\r\n" : "\n");
    266344    }
    267345
  • libcaca/trunk/cucul/import.c

    r1267 r1283  
    2323#       include <errno.h>
    2424#   endif
     25#   if defined(HAVE_ARPA_INET_H)
     26#       include <arpa/inet.h>
     27#   elif defined(HAVE_NETINET_IN_H)
     28#       include <netinet/in.h>
     29#   endif
    2530#   include <stdio.h>
    2631#   include <stdlib.h>
     
    3035#include "cucul.h"
    3136#include "cucul_internals.h"
     37
     38static inline uint32_t sscanu32(void const *s)
     39{
     40    uint32_t x;
     41    memcpy(&x, s, 4);
     42    return ntohl(x);
     43}
     44
     45static inline uint16_t sscanu16(void const *s)
     46{
     47    uint16_t x;
     48    memcpy(&x, s, 2);
     49    return ntohs(x);
     50}
    3251
    3352/* ANSI Graphic Rendition Combination Mode */
     
    86105
    87106        /* If 4 first letters are CACA */
    88         if(buffer->size >= 4 &&
    89            buf[0] == 'C' && buf[1] == 'A' && buf[2] == 'C' && buf[3] != 'A')
     107        if(buffer->size >= 4 && (uint8_t)buf[0] == 0xca &&
     108           (uint8_t)buf[1] == 0xca && buf[2] == 'C' && buf[3] == 'V')
    90109            return import_caca(buffer->data, buffer->size);
    91110
     
    138157    cucul_canvas_t *cv;
    139158    uint8_t const *buf = (uint8_t const *)data;
    140     unsigned int width, height, n;
    141 
    142     if(size < 16)
     159    unsigned int control_size, data_size, full_size, frames, f, n;
     160    uint16_t version, flags;
     161
     162    if(size < 20)
    143163        goto invalid_caca;
    144164
    145     if(buf[0] != 'C' || buf[1] != 'A' || buf[2] != 'C' || buf[3] != 'A')
     165    if(buf[0] != 0xca || buf[1] != 0xca || buf[2] != 'C' || buf[3] != 'V')
    146166        goto invalid_caca;
    147167
    148     if(buf[4] != 'C' || buf[5] != 'A' || buf[6] != 'N' || buf[7] != 'V')
     168    control_size = sscanu32(buf + 4);
     169    data_size = sscanu32(buf + 8);
     170    version = sscanu16(buf + 12);
     171    frames = sscanu32(buf + 14);
     172    flags = sscanu16(buf + 18);
     173
     174    if(size != 4 + control_size + data_size)
    149175        goto invalid_caca;
    150176
    151     width = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
    152         | ((uint32_t)buf[10] << 8) | (uint32_t)buf[11];
    153     height = ((uint32_t)buf[12] << 24) | ((uint32_t)buf[13] << 16)
    154         | ((uint32_t)buf[14] << 8) | (uint32_t)buf[15];
    155 
    156     if(size != 16 + width * height * 8)
     177    if(control_size < 16 + frames * 24)
    157178        goto invalid_caca;
    158179
    159     cv = cucul_create_canvas(width, height);
     180    for(full_size = 0, f = 0; f < frames; f++)
     181    {
     182        unsigned int width, height, duration;
     183        uint32_t attr;
     184        int x, y;
     185
     186        width = sscanu32(buf + 4 + 16 + f * 24);
     187        height = sscanu32(buf + 4 + 16 + f * 24 + 4);
     188        duration = sscanu32(buf + 4 + 16 + f * 24 + 8);
     189        attr = sscanu32(buf + 4 + 16 + f * 24 + 12);
     190        x = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 16);
     191        y = (int32_t)sscanu32(buf + 4 + 16 + f * 24 + 20);
     192
     193        full_size += width * height * 8;
     194    }
     195
     196    if(full_size != data_size)
     197        goto invalid_caca;
     198
     199    /* FIXME: read all frames, not only the first one */
     200    cv = cucul_create_canvas(sscanu32(buf + 4 + 16),
     201                             sscanu32(buf + 4 + 16 + 4));
    160202
    161203    if(!cv)
     
    167209    }
    168210
    169     for(n = height * width; n--; )
    170     {
    171         cv->chars[n] = ((uint32_t)buf[16 + 0 + 8 * n] << 24)
    172             | ((uint32_t)buf[16 + 1 + 8 * n] << 16)
    173             | ((uint32_t)buf[16 + 2 + 8 * n] << 8)
    174             | (uint32_t)buf[16 + 3 + 8 * n];
    175         cv->attrs[n] = ((uint32_t)buf[16 + 4 + 8 * n] << 24)
    176             | ((uint32_t)buf[16 + 5 + 8 * n] << 16)
    177             | ((uint32_t)buf[16 + 6 + 8 * n] << 8)
    178             | (uint32_t)buf[16 + 7 + 8 * n];
    179     }
     211    for(n = sscanu32(buf + 4 + 16) * sscanu32(buf + 4 + 16 + 4); n--; )
     212    {
     213        cv->chars[n] = sscanu32(buf + 4 + control_size + 8 * n);
     214        cv->attrs[n] = sscanu32(buf + 4 + control_size + 8 * n + 4);
     215    }
     216
     217    cv->curattr = sscanu32(buf + 4 + 16 + 12);
    180218
    181219    return cv;
  • libcaca/trunk/src/cacaserver.c

    r950 r1283  
    143143    server = malloc(sizeof(struct server));
    144144
    145     server->input = malloc(16);
     145    server->input = malloc(12);
    146146    server->read = 0;
    147147
     
    207207        cucul_buffer_t *b;
    208208        uint8_t *buf = server->input;
    209         uint32_t width, height;
     209        uint32_t control_size, data_size;
    210210        unsigned int size;
    211211
     
    215215
    216216        /* Read data from stdin */
    217         read(0, buf, 16);
    218 
    219         while(buf[0] != 'C' || buf[1] != 'A' || buf[2] != 'C' || buf[3] != 'A')
    220         {
    221             memmove(buf, buf + 1, 15);
    222             read(0, buf + 15, 1);
    223         }
    224 
    225         width = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
     217        read(0, buf, 12);
     218
     219        while(buf[0] != 0xca || buf[1] != 0xca
     220               || buf[2] != 'C' || buf[3] != 'V')
     221        {
     222            memmove(buf, buf + 1, 11);
     223            read(0, buf + 11, 1);
     224        }
     225
     226        control_size = ((uint32_t)buf[4] << 24) | ((uint32_t)buf[5] << 16)
     227               | ((uint32_t)buf[6] << 8) | (uint32_t)buf[7];
     228        data_size = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
    226229               | ((uint32_t)buf[10] << 8) | (uint32_t)buf[11];
    227         height = ((uint32_t)buf[12] << 24) | ((uint32_t)buf[13] << 16)
    228                 | ((uint32_t)buf[14] << 8) | (uint32_t)buf[15];
    229 
    230         size = 16 + width * height * 8;
     230
     231        size = 4 + control_size + data_size;
    231232        buf = server->input = realloc(server->input, size);
    232         read(0, buf + 16, size - 16);
     233        read(0, buf + 12, size - 12);
    233234
    234235        /* Free the previous canvas, if any */
     
    251252
    252253        /* Get ANSI representation of the image and skip the end-of buffer
    253          * linefeed ("\r\n", 2 bytes) */
    254         server->buffer = cucul_export_canvas(server->canvas, "utf8");
     254         * linefeed ("\r\n", 2 byte) */
     255        server->buffer = cucul_export_canvas(server->canvas, "utf8cr");
    255256        server->bufdata = cucul_get_buffer_data(server->buffer);
    256257        server->buflen = cucul_get_buffer_size(server->buffer);
Note: See TracChangeset for help on using the changeset viewer.