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.

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