You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * libcucul Canvas for ultrafast compositing of Unicode letters
  3. * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the Do What The Fuck You Want To
  10. * Public License, Version 2, as published by Sam Hocevar. See
  11. * http://sam.zoy.org/wtfpl/COPYING for more details.
  12. */
  13. /*
  14. * This file contains various import functions.
  15. */
  16. #include "config.h"
  17. #include "common.h"
  18. #if !defined(__KERNEL__)
  19. # include <stdio.h>
  20. # include <stdlib.h>
  21. # include <string.h>
  22. #endif
  23. #include "cucul.h"
  24. #include "cucul_internals.h"
  25. static cucul_canvas_t *import_caca(void const *, unsigned int);
  26. static cucul_canvas_t *import_text(void const *, unsigned int);
  27. /** \brief Import a buffer into a canvas
  28. *
  29. * This function imports a memory area into an internal libcucul canvas.
  30. *
  31. * Valid values for \c format are:
  32. *
  33. * \li \c "": attempt to autodetect the file format.
  34. *
  35. * \li \c "caca": import native libcaca files.
  36. *
  37. * \param data The memory area to be loaded into a canvas.
  38. * \param size The length of the memory area.
  39. * \param format A string describing the input format.
  40. * \return A libcucul canvas, or NULL in case of error.
  41. */
  42. cucul_canvas_t * cucul_import_canvas(void const *data, unsigned int size,
  43. char const *format)
  44. {
  45. if(!strcasecmp("caca", format))
  46. return import_caca(data, size);
  47. if(!strcasecmp("text", format))
  48. return import_text(data, size);
  49. /* FIXME: Try to autodetect */
  50. if(!strcasecmp("", format))
  51. return import_caca(data, size);
  52. return NULL;
  53. }
  54. /** \brief Get available import formats
  55. *
  56. * Return a list of available import formats. The list is a NULL-terminated
  57. * array of strings, interleaving a string containing the internal value for
  58. * the import format, to be used with cucul_import_canvas(), and a string
  59. * containing the natural language description for that import format.
  60. *
  61. * \return An array of strings.
  62. */
  63. char const * const * cucul_get_import_list(void)
  64. {
  65. static char const * const list[] =
  66. {
  67. "", "autodetect",
  68. "text", "plain text",
  69. "caca", "native libcaca format",
  70. NULL, NULL
  71. };
  72. return list;
  73. }
  74. /*
  75. * XXX: the following functions are local.
  76. */
  77. static cucul_canvas_t *import_caca(void const *data, unsigned int size)
  78. {
  79. cucul_canvas_t *cv;
  80. uint8_t const *buf = (uint8_t const *)data;
  81. unsigned int width, height, n;
  82. if(size < 16)
  83. return NULL;
  84. if(buf[0] != 'C' || buf[1] != 'A' || buf[2] != 'C' || buf[3] != 'A')
  85. return NULL;
  86. if(buf[4] != 'C' || buf[5] != 'A' || buf[6] != 'N' || buf[7] != 'V')
  87. return NULL;
  88. width = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16)
  89. | ((uint32_t)buf[10] << 8) | (uint32_t)buf[11];
  90. height = ((uint32_t)buf[12] << 24) | ((uint32_t)buf[13] << 16)
  91. | ((uint32_t)buf[14] << 8) | (uint32_t)buf[15];
  92. if(!width || !height)
  93. return NULL;
  94. if(size != 16 + width * height * 8)
  95. return NULL;
  96. cv = cucul_create_canvas(width, height);
  97. if(!cv)
  98. return NULL;
  99. for(n = height * width; n--; )
  100. {
  101. cv->chars[n] = ((uint32_t)buf[16 + 0 + 8 * n] << 24)
  102. | ((uint32_t)buf[16 + 1 + 8 * n] << 16)
  103. | ((uint32_t)buf[16 + 2 + 8 * n] << 8)
  104. | (uint32_t)buf[16 + 3 + 8 * n];
  105. cv->attr[n] = ((uint32_t)buf[16 + 4 + 8 * n] << 24)
  106. | ((uint32_t)buf[16 + 5 + 8 * n] << 16)
  107. | ((uint32_t)buf[16 + 6 + 8 * n] << 8)
  108. | (uint32_t)buf[16 + 7 + 8 * n];
  109. }
  110. return cv;
  111. }
  112. static cucul_canvas_t *import_text(void const *data, unsigned int size)
  113. {
  114. cucul_canvas_t *cv;
  115. char const *text = (char const *)data;
  116. unsigned int width = 1, height = 1, x = 0, y = 0, i;
  117. cv = cucul_create_canvas(width, height);
  118. cucul_set_color(cv, CUCUL_COLOR_DEFAULT, CUCUL_COLOR_TRANSPARENT);
  119. for(i = 0; i < size; i++)
  120. {
  121. unsigned char ch = *text++;
  122. if(ch == '\r')
  123. continue;
  124. if(ch == '\n')
  125. {
  126. x = 0;
  127. y++;
  128. continue;
  129. }
  130. while(x >= width)
  131. {
  132. width++;
  133. cucul_set_canvas_size(cv, width, height);
  134. }
  135. while(y >= height)
  136. {
  137. height++;
  138. cucul_set_canvas_size(cv, width, height);
  139. }
  140. cucul_putchar(cv, x, y, ch);
  141. x++;
  142. }
  143. return cv;
  144. }