bmp.c
上传用户:hengzhunsh
上传日期:2013-09-07
资源大小:19k
文件大小:5k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*
  2.     fbv  --  simple image viewer for the linux framebuffer
  3.     Copyright (C) 2002  Tomasz Sterna
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.     This program is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     GNU General Public License for more details.
  12.     You should have received a copy of the GNU General Public License
  13.     along with this program; if not, write to the Free Software
  14.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "config.h"
  17. #ifdef FBV_SUPPORT_BMP
  18. #include "fbv.h"
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <fcntl.h>
  22. #include <unistd.h>
  23. #define BMP_TORASTER_OFFSET 10
  24. #define BMP_SIZE_OFFSET 18
  25. #define BMP_BPP_OFFSET 28
  26. #define BMP_RLE_OFFSET 30
  27. #define BMP_COLOR_OFFSET 54
  28. #define fill4B(a) ( ( 4 - ( (a) % 4 ) ) & 0x03)
  29. struct color {
  30. unsigned char red;
  31. unsigned char green;
  32. unsigned char blue;
  33. };
  34. int fh_bmp_id(char *name)
  35. {
  36. int fd;
  37. char id[2];
  38. fd = open(name, O_RDONLY);
  39. if (fd == -1) {
  40. return(0);
  41. }
  42. read(fd, id, 2);
  43. close(fd);
  44. if ( id[0]=='B' && id[1]=='M' ) {
  45. return(1);
  46. }
  47. return(0);
  48. }
  49. void fetch_pallete(int fd, struct color pallete[], int count)
  50. {
  51. unsigned char buff[4];
  52. int i;
  53. lseek(fd, BMP_COLOR_OFFSET, SEEK_SET);
  54. for (i=0; i<count; i++) {
  55. read(fd, buff, 4);
  56. pallete[i].red = buff[2];
  57. pallete[i].green = buff[1];
  58. pallete[i].blue = buff[0];
  59. }
  60. return;
  61. }
  62. int fh_bmp_load(char *name,unsigned char *buffer, unsigned char **alpha, int x,int y)
  63. {
  64. int fd, bpp, raster, i, j, k, skip;
  65. unsigned char buff[4];
  66. unsigned char *wr_buffer = buffer + x*(y-1)*3;
  67. struct color pallete[256];
  68. fd = open(name, O_RDONLY);
  69. if (fd == -1) {
  70. return(FH_ERROR_FILE);
  71. }
  72. if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) {
  73. return(FH_ERROR_FORMAT);
  74. }
  75. read(fd, buff, 4);
  76. raster = buff[0] + (buff[1]<<8) + (buff[2]<<16) + (buff[3]<<24);
  77. if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) {
  78. return(FH_ERROR_FORMAT);
  79. }
  80. read(fd, buff, 2);
  81. bpp = buff[0] + (buff[1]<<8);
  82. switch (bpp){
  83. case 1: /* monochrome */
  84. skip = fill4B(x/8+(x%8?1:0));
  85. lseek(fd, raster, SEEK_SET);
  86. for (i=0; i<y; i++) {
  87. for (j=0; j<x/8; j++) {
  88. read(fd, buff, 1);
  89. for (k=0; k<8; k++) {
  90. if (buff[0] & 0x80) {
  91. *wr_buffer++ = 0xff;
  92. *wr_buffer++ = 0xff;
  93. *wr_buffer++ = 0xff;
  94. } else {
  95. *wr_buffer++ = 0x00;
  96. *wr_buffer++ = 0x00;
  97. *wr_buffer++ = 0x00;
  98. }
  99. buff[0] = buff[0]<<1;
  100. }
  101. }
  102. if (x%8) {
  103. read(fd, buff, 1);
  104. for (k=0; k<x%8; k++) {
  105. if (buff[0] & 0x80) {
  106. *wr_buffer++ = 0xff;
  107. *wr_buffer++ = 0xff;
  108. *wr_buffer++ = 0xff;
  109. } else {
  110. *wr_buffer++ = 0x00;
  111. *wr_buffer++ = 0x00;
  112. *wr_buffer++ = 0x00;
  113. }
  114. buff[0] = buff[0]<<1;
  115. }
  116. }
  117. if (skip) {
  118. read(fd, buff, skip);
  119. }
  120. wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
  121. }
  122. break;
  123. case 4: /* 4bit palletized */
  124. skip = fill4B(x/2+x%2);
  125. fetch_pallete(fd, pallete, 16);
  126. lseek(fd, raster, SEEK_SET);
  127. for (i=0; i<y; i++) {
  128. for (j=0; j<x/2; j++) {
  129. read(fd, buff, 1);
  130. buff[1] = buff[0]>>4;
  131. buff[2] = buff[0] & 0x0f;
  132. *wr_buffer++ = pallete[buff[1]].red;
  133. *wr_buffer++ = pallete[buff[1]].green;
  134. *wr_buffer++ = pallete[buff[1]].blue;
  135. *wr_buffer++ = pallete[buff[2]].red;
  136. *wr_buffer++ = pallete[buff[2]].green;
  137. *wr_buffer++ = pallete[buff[2]].blue;
  138. }
  139. if (x%2) {
  140. read(fd, buff, 1);
  141. buff[1] = buff[0]>>4;
  142. *wr_buffer++ = pallete[buff[1]].red;
  143. *wr_buffer++ = pallete[buff[1]].green;
  144. *wr_buffer++ = pallete[buff[1]].blue;
  145. }
  146. if (skip) {
  147. read(fd, buff, skip);
  148. }
  149. wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
  150. }
  151. break;
  152. case 8: /* 8bit palletized */
  153. skip = fill4B(x);
  154. fetch_pallete(fd, pallete, 256);
  155. lseek(fd, raster, SEEK_SET);
  156. for (i=0; i<y; i++) {
  157. for (j=0; j<x; j++) {
  158. read(fd, buff, 1);
  159. *wr_buffer++ = pallete[buff[0]].red;
  160. *wr_buffer++ = pallete[buff[0]].green;
  161. *wr_buffer++ = pallete[buff[0]].blue;
  162. }
  163. if (skip) {
  164. read(fd, buff, skip);
  165. }
  166. wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
  167. }
  168. break;
  169. case 16: /* 16bit RGB */
  170. return(FH_ERROR_FORMAT);
  171. break;
  172. case 24: /* 24bit RGB */
  173. skip = fill4B(x*3);
  174. lseek(fd, raster, SEEK_SET);
  175. for (i=0; i<y; i++) {
  176. for (j=0; j<x; j++) {
  177. read(fd, buff, 3);
  178. *wr_buffer++ = buff[2];
  179. *wr_buffer++ = buff[1];
  180. *wr_buffer++ = buff[0];
  181. }
  182. if (skip) {
  183. read(fd, buff, skip);
  184. }
  185. wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
  186. }
  187. break;
  188. default:
  189. return(FH_ERROR_FORMAT);
  190. }
  191. close(fd);
  192. return(FH_ERROR_OK);
  193. }
  194. int fh_bmp_getsize(char *name,int *x,int *y)
  195. {
  196. int fd;
  197. unsigned char size[4];
  198. fd = open(name, O_RDONLY);
  199. if (fd == -1) {
  200. return(FH_ERROR_FILE);
  201. }
  202. if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) {
  203. return(FH_ERROR_FORMAT);
  204. }
  205. read(fd, size, 4);
  206. *x = size[0] + (size[1]<<8) + (size[2]<<16) + (size[3]<<24);
  207. // *x-=1;
  208. read(fd, size, 4);
  209. *y = size[0] + (size[1]<<8) + (size[2]<<16) + (size[3]<<24);
  210. close(fd);
  211. return(FH_ERROR_OK);
  212. }
  213. #endif