Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

309 рядки
9.1 KiB

  1. /*
  2. * view image viewer for libcaca
  3. * Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  21. * 02111-1307 USA
  22. */
  23. #include "config.h"
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <malloc.h>
  27. #include <unistd.h>
  28. #include <Imlib2.h>
  29. #include "caca.h"
  30. Imlib_Image image = NULL;
  31. char *pixels = NULL;
  32. struct caca_bitmap *bitmap = NULL;
  33. int x, y, w, h;
  34. const unsigned int rmask = 0x00ff0000, gmask = 0x0000ff00, bmask = 0x000000ff;
  35. int dithering = CACA_DITHERING_ORDERED4;
  36. static void load_image(const char *);
  37. int main(int argc, char **argv)
  38. {
  39. int quit = 0, update = 1, help = 0, reload = 0;
  40. int i, zoom = 0;
  41. char **list = NULL;
  42. int current = 0, items = 0, opts = 1;
  43. /* Initialise libcaca */
  44. if(caca_init())
  45. {
  46. fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
  47. return 1;
  48. }
  49. /* Load items into playlist */
  50. for(i = 1; i < argc; i++)
  51. {
  52. /* Skip options except after `--' */
  53. if(opts && argv[i][0] == '-')
  54. {
  55. if(argv[i][1] == '-' && argv[i][2] == '\0')
  56. opts = 0;
  57. continue;
  58. }
  59. /* Add argv[i] to the list */
  60. if(items)
  61. list = realloc(list, (items + 1) * sizeof(char *));
  62. else
  63. list = malloc(sizeof(char *));
  64. list[items] = argv[i];
  65. items++;
  66. reload = 1;
  67. }
  68. /* Go ! */
  69. while(!quit)
  70. {
  71. int ww = caca_get_width();
  72. int wh = caca_get_height();
  73. int event;
  74. while((event = caca_get_event()))
  75. {
  76. switch(event)
  77. {
  78. case CACA_EVENT_KEY_PRESS | 'n':
  79. case CACA_EVENT_KEY_PRESS | 'N':
  80. if(items) current = (current + 1) % items;
  81. reload = 1;
  82. break;
  83. case CACA_EVENT_KEY_PRESS | 'p':
  84. case CACA_EVENT_KEY_PRESS | 'P':
  85. if(items) current = (items + current - 1) % items;
  86. reload = 1;
  87. break;
  88. case CACA_EVENT_KEY_PRESS | 'd':
  89. dithering = (dithering + 1) % 5;
  90. update = 1;
  91. break;
  92. case CACA_EVENT_KEY_PRESS | 'D':
  93. dithering = (dithering + 4) % 5;
  94. update = 1;
  95. break;
  96. case CACA_EVENT_KEY_PRESS | '+':
  97. zoom++;
  98. if(zoom > 48) zoom = 48; else update = 1;
  99. break;
  100. case CACA_EVENT_KEY_PRESS | '-':
  101. zoom--;
  102. if(zoom < -48) zoom = -48; else update = 1;
  103. break;
  104. case CACA_EVENT_KEY_PRESS | 'x':
  105. case CACA_EVENT_KEY_PRESS | 'X':
  106. zoom = 0;
  107. update = 1;
  108. break;
  109. case CACA_EVENT_KEY_PRESS | 'k':
  110. case CACA_EVENT_KEY_PRESS | 'K':
  111. case CACA_EVENT_KEY_PRESS | CACA_KEY_UP:
  112. if(zoom > 0) y -= 1 + h / (2 + zoom) / 8;
  113. update = 1;
  114. break;
  115. case CACA_EVENT_KEY_PRESS | 'j':
  116. case CACA_EVENT_KEY_PRESS | 'J':
  117. case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN:
  118. if(zoom > 0) y += 1 + h / (2 + zoom) / 8;
  119. update = 1;
  120. break;
  121. case CACA_EVENT_KEY_PRESS | 'h':
  122. case CACA_EVENT_KEY_PRESS | 'H':
  123. case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT:
  124. if(zoom > 0) x -= 1 + w / (2 + zoom) / 8;
  125. update = 1;
  126. break;
  127. case CACA_EVENT_KEY_PRESS | 'l':
  128. case CACA_EVENT_KEY_PRESS | 'L':
  129. case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT:
  130. if(zoom > 0) x += 1 + w / (2 + zoom) / 8;
  131. update = 1;
  132. break;
  133. case CACA_EVENT_KEY_PRESS | '?':
  134. help = 1;
  135. update = 1;
  136. break;
  137. case CACA_EVENT_KEY_PRESS | 'q':
  138. case CACA_EVENT_KEY_PRESS | 'Q':
  139. quit = 1;
  140. break;
  141. }
  142. }
  143. if(items && reload)
  144. {
  145. char *buffer = malloc(ww + 1);
  146. /* Reset image-specific runtime variables */
  147. zoom = 0;
  148. snprintf(buffer, ww, " Loading `%s'... ", list[current]);
  149. buffer[ww] = '\0';
  150. caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
  151. caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
  152. caca_refresh();
  153. load_image(list[current]);
  154. reload = 0;
  155. update = 1;
  156. free(buffer);
  157. }
  158. if(!update)
  159. {
  160. usleep(10000);
  161. continue;
  162. }
  163. caca_clear();
  164. caca_set_dithering(dithering);
  165. caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
  166. if(!items)
  167. caca_printf(ww / 2 - 5, wh / 2, " No image. ");
  168. else if(!image)
  169. {
  170. char *buffer = malloc(ww + 1);
  171. snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
  172. buffer[ww] = '\0';
  173. caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
  174. free(buffer);
  175. }
  176. else if(zoom < 0)
  177. {
  178. int xo = (ww - 1) / 2;
  179. int yo = (wh - 1) / 2;
  180. int xn = (ww - 1) / (2 - zoom);
  181. int yn = (wh - 1) / (2 - zoom);
  182. caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn,
  183. bitmap, pixels);
  184. }
  185. else if(zoom > 0)
  186. {
  187. struct caca_bitmap *newbitmap;
  188. int xn = w / (2 + zoom);
  189. int yn = h / (2 + zoom);
  190. if(x < xn) x = xn;
  191. if(y < yn) y = yn;
  192. if(xn + x > w) x = w - xn;
  193. if(yn + y > h) y = h - yn;
  194. newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
  195. rmask, gmask, bmask);
  196. caca_draw_bitmap(0, 0, ww - 1, wh - 1, newbitmap,
  197. pixels + 4 * (x - xn) + 4 * w * (y - yn));
  198. caca_free_bitmap(newbitmap);
  199. }
  200. else
  201. {
  202. caca_draw_bitmap(0, 0, ww - 1, wh - 1, bitmap, pixels);
  203. }
  204. caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
  205. caca_draw_line(0, 0, ww - 1, 0, ' ');
  206. caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
  207. caca_putstr(0, 0, "q:Quit n/p:Next/Prev +/-/x:Zoom "
  208. "h/j/k/l: Move d:Dithering");
  209. caca_putstr(ww - strlen("?:Help"), 0, "?:Help");
  210. caca_printf(3, wh - 1, "cacaview %s", VERSION);
  211. caca_printf(ww / 2 - 5, wh - 1, "(%s dithering)",
  212. caca_get_dithering_name(dithering));
  213. caca_printf(ww - 14, wh - 1,
  214. "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
  215. if(help)
  216. {
  217. caca_putstr(ww - 22, 2, " +: zoom in ");
  218. caca_putstr(ww - 22, 3, " -: zoom out ");
  219. caca_putstr(ww - 22, 4, " x: reset zoom ");
  220. caca_putstr(ww - 22, 5, " ------------------- ");
  221. caca_putstr(ww - 22, 6, " hjkl: move view ");
  222. caca_putstr(ww - 22, 7, " arrows: move view ");
  223. caca_putstr(ww - 22, 8, " ------------------- ");
  224. caca_putstr(ww - 22, 9, " d: dithering method ");
  225. caca_putstr(ww - 22, 10, " ------------------- ");
  226. caca_putstr(ww - 22, 11, " ?: help ");
  227. caca_putstr(ww - 22, 12, " q: quit ");
  228. help = 0;
  229. }
  230. caca_refresh();
  231. update = 0;
  232. }
  233. if(bitmap)
  234. caca_free_bitmap(bitmap);
  235. if(image)
  236. imlib_free_image();
  237. /* Clean up */
  238. caca_end();
  239. return 0;
  240. }
  241. static void load_image(const char *name)
  242. {
  243. /* Empty previous data */
  244. if(image)
  245. imlib_free_image();
  246. if(bitmap)
  247. caca_free_bitmap(bitmap);
  248. image = NULL;
  249. bitmap = NULL;
  250. /* Load the new image */
  251. image = imlib_load_image(name);
  252. if(!image)
  253. {
  254. return;
  255. }
  256. imlib_context_set_image(image);
  257. pixels = (char *)imlib_image_get_data_for_reading_only();
  258. w = imlib_image_get_width();
  259. h = imlib_image_get_height();
  260. x = w / 2;
  261. y = h / 2;
  262. /* Create the libcaca bitmap */
  263. bitmap = caca_create_bitmap(32, w, h, 4 * w, rmask, gmask, bmask);
  264. if(!bitmap)
  265. {
  266. imlib_free_image();
  267. image = NULL;
  268. }
  269. }