counter.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include <math.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <png.h>
  5. #include "counter.h"
  6. #include "powers_table.h"
  7. #include "digits_data.h"
  8. static int count_digits(unsigned long number) {
  9. for (int i = 1; i < POWERS_COUNT; i++)
  10. if (number < powers_table[i][0]) return powers_table[i][1];
  11. return powers_table[POWERS_COUNT-1][1];
  12. }
  13. static int nth_digit(unsigned long number, int n) {
  14. return (number / powers_table[n][0]) % 10;
  15. }
  16. void counter_create(unsigned long number, FILE *fd) {
  17. png_structp png;
  18. png_infop info;
  19. int digits_count;
  20. int width;
  21. int digits[POWERS_COUNT];
  22. png_byte **rows;
  23. png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  24. info = png_create_info_struct(png);
  25. digits_count = count_digits(number);
  26. width = digits_count * DIGIT_WIDTH;
  27. rows = malloc(sizeof(png_byte *) * DIGIT_HEIGHT);
  28. for (int i = 0; i < digits_count; i++)
  29. digits[i] = nth_digit(number, digits_count-1-i);
  30. for (int y = 0; y < DIGIT_HEIGHT; y++) {
  31. rows[y] = malloc(width * 4);
  32. for (int i = 0; i < digits_count; i++)
  33. memcpy(rows[y] + (i * DIGIT_WIDTH * 4), digits_data[digits[i]][y], DIGIT_WIDTH * 4);
  34. }
  35. png_init_io(png, fd);
  36. png_set_IHDR(
  37. png,
  38. info,
  39. width,
  40. DIGIT_HEIGHT,
  41. 8,
  42. PNG_COLOR_TYPE_RGBA,
  43. PNG_INTERLACE_NONE,
  44. PNG_COMPRESSION_TYPE_BASE,
  45. PNG_FILTER_TYPE_BASE
  46. );
  47. png_write_info(png, info);
  48. png_write_image(png, rows);
  49. png_write_end(png, info);
  50. png_destroy_write_struct(&png, &info);
  51. for (int y = 0; y < DIGIT_HEIGHT; y++)
  52. free(rows[y]);
  53. free(rows);
  54. }