A bunch of random code samples
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

118 lignes
3.1 KiB

  1. /*
  2. cmake_minimum_required(VERSION 3.28)
  3. project(codiceps)
  4. set(CMAKE_CXX_STANDARD 23)
  5. include(FetchContent)
  6. FetchContent_Declare(
  7. raylib
  8. GIT_REPOSITORY https://github.com/raysan5/raylib.git
  9. GIT_TAG 5.0
  10. )
  11. FetchContent_MakeAvailable(raylib)
  12. add_executable(codiceps codiceps.cpp)
  13. target_link_libraries(codiceps PUBLIC raylib_static)
  14. */
  15. #include <ranges>
  16. #include <iostream>
  17. #include <fstream>
  18. #include <sstream>
  19. #include <vector>
  20. #include <cassert>
  21. #include "raylib.h"
  22. std::string slurp(const char* filename) {
  23. std::ifstream file{filename};
  24. std::stringstream data;
  25. file >> data.rdbuf();
  26. return data.str();
  27. }
  28. std::vector<bool> to_bits(std::string str) {
  29. std::vector<bool> d;
  30. for(char c : str) {
  31. d.push_back(c & 0b10000000);
  32. d.push_back(c & 0b1000000);
  33. d.push_back(c & 0b100000);
  34. d.push_back(c & 0b10000);
  35. d.push_back(c & 0b1000);
  36. d.push_back(c & 0b100);
  37. d.push_back(c & 0b10);
  38. d.push_back(c & 0b1);
  39. }
  40. return d;
  41. }
  42. std::string from_bits(std::vector<bool> data) {
  43. std::string d;
  44. for(auto composite : data | std::views::chunk(8)) {
  45. char c = 0;
  46. for(auto b : composite) {
  47. c *= 2;
  48. c += b;
  49. }
  50. d.push_back(c);
  51. }
  52. return d;
  53. }
  54. void encode(const char* pic, const char* data_source) {
  55. auto image = LoadImage(pic);
  56. auto raw_data = slurp(data_source);
  57. std::vector<bool> raw_bits = to_bits(raw_data);
  58. assert(raw_bits.size() % 8 == 0);
  59. assert(raw_bits.size() / 8 == raw_data.size());
  60. size_t idx = 0;
  61. for(auto j : std::ranges::iota_view(0, image.height)) {
  62. for(auto i : std::ranges::iota_view(0, image.width)) {
  63. auto c = GetImageColor(image, i, j);
  64. c.r ^= c.r & 1;
  65. c.g ^= c.g & 1;
  66. c.b ^= c.b & 1;
  67. c.r += idx < raw_bits.size() ? raw_bits[idx] : 0; idx++;
  68. c.g += idx < raw_bits.size() ? raw_bits[idx] : 0; idx++;
  69. c.b += idx < raw_bits.size() ? raw_bits[idx] : 0; idx++;
  70. ImageDrawPixel(&image, i, j, c);
  71. }
  72. }
  73. ExportImage(image, pic);
  74. UnloadImage(image);
  75. if(raw_bits.size() > idx) {
  76. std::cout << "\x1b[1;31mWritten bits: " << raw_bits.size() << "/" << idx << std::endl;
  77. } else {
  78. std::cout << "\x1b[1;32mWritten bits: " << raw_bits.size() << "/" << idx << std::endl;
  79. }
  80. }
  81. void decode(const char* pic) {
  82. auto image = LoadImage(pic);
  83. std::vector<bool> raw_bits;
  84. size_t idx = 0;
  85. for(auto j : std::ranges::iota_view(0, image.height)) {
  86. for(auto i : std::ranges::iota_view(0, image.width)) {
  87. auto c = GetImageColor(image, i, j);
  88. raw_bits.push_back(c.r & 1);
  89. raw_bits.push_back(c.g & 1);
  90. raw_bits.push_back(c.b & 1);
  91. }
  92. }
  93. UnloadImage(image);
  94. std::cout << from_bits(raw_bits).c_str() << std::endl;
  95. }
  96. int main(int argc, char** argv) {
  97. if(argc < 1) {
  98. perror("arguments missing, expected: picture then datafile for coding, picture for decoding");
  99. }
  100. if(argc == 3) {
  101. encode(argv[1], argv[2]);
  102. } else if(argc == 2) {
  103. decode(argv[1]);
  104. }
  105. return 0;
  106. }