hdc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include <sys/types.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "libpng/png.h"
  5. typedef unsigned char uint8_t;
  6. typedef unsigned short uint16_t;
  7. typedef unsigned int uint32_t;
  8. typedef unsigned int hdc_color_t;
  9. typedef unsigned short hdc_pixel_t;
  10. #define HDC_ARGB(a, r, g, b) \
  11. ((hdc_color_t)(((uint8_t)(r)|\
  12. (((unsigned)(uint8_t)(g))<<8))|\
  13. (((unsigned long)(uint8_t)(b))<<16)|\
  14. (((unsigned long)(uint8_t)(a))<<24)))
  15. #define HDC_RGB(r, g, b) HDC_ARGB(255, (r), (g), (b))
  16. #define HDC_RGB_R(c) ((c) & 0xff)
  17. #define HDC_RGB_G(c) (((c) >> 8) & 0xff)
  18. #define HDC_RGB_B(c) (((c) >> 16) & 0xff)
  19. #define HDC_RGB_A(c) (((c) >> 24) & 0xff)
  20. /* convert HDC color to BBBBBGGGGGGRRRRR */
  21. uint16_t hdc_color_to_565(hdc_color_t c)
  22. {
  23. uint16_t pixel;
  24. pixel = ((HDC_RGB_B(c)>> 3) << 11) | ((HDC_RGB_G(c) >> 2) << 5) | (HDC_RGB_R(c) >> 3);
  25. return pixel;
  26. }
  27. /* convert HDC color to RRRRRGGGGGGBBBBB */
  28. uint16_t hdc_color_to_565p(hdc_color_t c)
  29. {
  30. uint16_t pixel;
  31. pixel = ((HDC_RGB_R(c) >> 3) << 11) | ((HDC_RGB_G(c) >> 2) << 5) | (HDC_RGB_B(c)>> 3);
  32. return pixel;
  33. }
  34. /* png image information */
  35. png_structp png_ptr;
  36. png_infop info_ptr;
  37. struct hdc_image_header
  38. {
  39. uint32_t magic;
  40. uint32_t width;
  41. uint32_t height;
  42. /* transparent color */
  43. uint32_t tmask;
  44. /* reserved */
  45. uint32_t reserved;
  46. };
  47. struct hdc_image_header header;
  48. int main(int argc, char** argv)
  49. {
  50. int bit_depth;
  51. int color_type;
  52. double gamma;
  53. int width, height;
  54. FILE *src_fp, *dst_fp;
  55. png_uint_32 x, y;
  56. png_bytep row;
  57. png_bytep data;
  58. hdc_pixel_t *ptr;
  59. src_fp = fopen(argv[1], "rb");
  60. dst_fp = fopen(argv[2], "wb");
  61. if (src_fp == NULL || dst_fp == NULL)
  62. {
  63. printf("can't open file for read or write\n");
  64. return -1;
  65. }
  66. png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  67. if (png_ptr == NULL)
  68. {
  69. return -1;
  70. }
  71. info_ptr = png_create_info_struct(png_ptr);
  72. if (info_ptr == NULL)
  73. {
  74. png_destroy_read_struct(&png_ptr, NULL, NULL);
  75. return -1;
  76. }
  77. if (setjmp(png_jmpbuf(png_ptr)))
  78. {
  79. png_read_end(png_ptr, NULL);
  80. /* destroy png struct */
  81. png_destroy_info_struct(png_ptr, &info_ptr);
  82. png_destroy_read_struct(&png_ptr, NULL, NULL);
  83. fclose(src_fp);fclose(dst_fp);
  84. return (-1);
  85. }
  86. png_init_io(png_ptr, src_fp);
  87. png_read_info(png_ptr, info_ptr);
  88. png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
  89. &color_type, NULL, NULL, NULL);
  90. if (bit_depth == 16)
  91. png_set_strip_16(png_ptr);
  92. if (color_type == PNG_COLOR_TYPE_PALETTE)
  93. png_set_expand(png_ptr);
  94. if (bit_depth < 8)
  95. png_set_expand(png_ptr);
  96. if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
  97. png_set_expand(png_ptr);
  98. if (color_type == PNG_COLOR_TYPE_GRAY ||
  99. color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  100. png_set_gray_to_rgb(png_ptr);
  101. /* set gamma conversion */
  102. if (png_get_gAMA(png_ptr, info_ptr, &gamma))
  103. png_set_gamma(png_ptr, (double)2.2, gamma);
  104. png_read_update_info(png_ptr, info_ptr);
  105. /* write HDC file header */
  106. sprintf((char *)&header.magic, "HDC%c", '\0');
  107. header.width = info_ptr->width;
  108. header.height = info_ptr->height;
  109. header.tmask = 0;
  110. header.reserved = 0;
  111. fwrite(&header, 1, sizeof(struct hdc_image_header), dst_fp);
  112. row = (png_bytep) malloc (png_get_rowbytes(png_ptr, info_ptr));
  113. if (row == NULL) goto _return;
  114. ptr = (hdc_pixel_t*) malloc (header.width * header.height * sizeof(hdc_pixel_t));
  115. switch (info_ptr->color_type)
  116. {
  117. case PNG_COLOR_TYPE_RGBA:
  118. for (y = 0; y < info_ptr->height; y++)
  119. {
  120. png_read_row(png_ptr, row, png_bytep_NULL);
  121. for (x = 0; x < info_ptr->width; x++)
  122. {
  123. data = &(row[x * 4]);
  124. ptr[x + y * info_ptr->width] = hdc_color_to_565p(HDC_ARGB((255 - data[3]), data[0], data[1], data[2]));
  125. }
  126. }
  127. break;
  128. case PNG_COLOR_TYPE_PALETTE:
  129. for (y = 0; y < info_ptr->height; y++)
  130. {
  131. png_read_row(png_ptr, row, png_bytep_NULL);
  132. for (x = 0; x < info_ptr->width; x++)
  133. {
  134. data = &(row[x]);
  135. ptr[x] = hdc_color_to_565p(HDC_ARGB(0, info_ptr->palette[data[0]].red,
  136. info_ptr->palette[data[0]].green,
  137. info_ptr->palette[data[0]].blue));
  138. }
  139. }
  140. default:
  141. break;
  142. };
  143. fwrite(ptr, 1, header.height * header.width * sizeof(hdc_pixel_t), dst_fp);
  144. _return:
  145. png_read_end(png_ptr, NULL);
  146. /* destroy png struct */
  147. png_destroy_info_struct(png_ptr, &info_ptr);
  148. png_destroy_read_struct(&png_ptr, NULL, NULL);
  149. fclose(src_fp);
  150. fclose(dst_fp);
  151. free(ptr);
  152. return 0;
  153. }