Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2019
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.99 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3.  
  4. #define palette_size 1024
  5. #define header_size 54
  6.  
  7. using namespace std;
  8.  
  9. enum CODE
  10. {
  11. WORD,
  12. DWORD
  13. };
  14.  
  15. int32_t pow(int32_t x)
  16. {
  17. return x*x;
  18. }
  19.  
  20. void BMP_code(uint8_t * source, uint8_t * dest, CODE type) /// Odczytuje kod w odwrotnej kolejnosci bajtow dla 2 bajtow i 4 bajtow
  21. {
  22. if(type == WORD)
  23. {
  24. dest[0] = source[0];
  25. dest[1] = source[1];
  26. }
  27. else if(type == DWORD)
  28. {
  29. dest[0] = source[0];
  30. dest[1] = source[1];
  31. dest[2] = source[2];
  32. dest[3] = source[3];
  33. }
  34. }
  35.  
  36. /// Moj wlasny algorytm na indeksowanie kolorow
  37. /// Polega on na obliczeniu roznicy szukanego koloru z kolorem palety i podniesieniu go do kwadratu
  38. /// Po obliczeniu 3 kolorow jest ono sumowane
  39. /// Dzieki temu preferowane jest wyszukiwanie blizszego koloru w odpowiedniku 8 bitowym
  40. /// Np. mamy 2 podobne kolory 1.(125,125,125) i 2.(120,120,120) w palecie
  41. /// i kolor (123,117,130), wyliczamy roznice dla obydwu wariantow
  42. /// 1: (125-123)^2+(125-117)^2+(130-125)^2=4+64+25=93
  43. /// 2: (123-120)^2+(120-117)^2+(130-120)^2=9+9+100=118
  44. /// To są wariancje teraz liczymy zwykla sume roznic
  45. /// 1: (125-123)+(125-117)+(130-125)=2+8+5=15
  46. /// 2: (123-120)+(120-117)+(130-120)=16
  47. /// Roznica sumy roznica jest duzo mniejsza od wariancji
  48. /// Wyliczenie na podstawie wariancji gwarantuje nam dobranie bardziej odpowiedniego koloru
  49. /// Tym samym ten algorytm jest ok
  50. int32_t GetColorIndex(int32_t r, int32_t g, int32_t b, uint8_t * palette)
  51. {
  52. int32_t temprange;
  53. int32_t range = pow(r-int32_t(palette[0]))+pow(g-int32_t(palette[1]))+pow(b-int32_t(palette[2]));
  54. int32_t index = 0;
  55.  
  56. for(int32_t a = 4; a<palette_size; a++)
  57. {
  58. temprange = pow(r-int32_t(palette[a]))+pow(g-int32_t(palette[a+1]))+pow(b-int32_t(palette[a+2]));
  59. if(temprange < range)
  60. {
  61. range = temprange;
  62. index = a/4;
  63. }
  64. }
  65.  
  66. return index;
  67. }
  68.  
  69. int main()
  70. {
  71. /// Nazwa pliku
  72. string filename;
  73.  
  74. /// Zmienne zawierajace cechy bitmapy
  75. uint8_t header[header_size]; /// Naglowek bitmapy
  76. uint8_t palette[palette_size]; /// Paleta kolorow dla bitmapy 8 bitowej
  77. uint8_t * sourcedata; /// Piksele
  78. uint8_t * destdata;
  79.  
  80. uint32_t sourcefilesize;
  81. uint32_t sourcepadding; /// Wartosc potrzebna do zaokraglenia do wielokrotnosci 4
  82. uint32_t sourcedatasize;
  83. uint32_t width, height;
  84.  
  85. uint32_t destdatasize;
  86. uint32_t destdatapadding;
  87.  
  88. /// Klasy potrzebne do odczytu lub zapisu pliku
  89. ifstream szablon_palety; /// Wczytuje domyslna palete kolorow
  90. ifstream BMP24; /// Źródło
  91. ofstream BMP8; /// Wynik
  92.  
  93. /// Program
  94. cout << "Nazwa pliku wraz z formatem:"; cin >> filename; cout << endl;
  95. cout << "Nastepuje otwieranie." << endl << endl;
  96. BMP24.open(filename.c_str(), ifstream::in | ifstream::binary);
  97. if(!BMP24.is_open()) /// Zabezpieczenie przed otwarciem nieistniejącego pliku
  98. {
  99. cout << "Blad. Pliku zrodlowego nie udalo sie otworzyc." << endl;
  100. system("pause");
  101. exit(0);
  102. }
  103. cout << "Plik zrodlowy jest otwarty." << endl << endl;
  104.  
  105. cout << "Nastepuje odczytywanie naglowka." << endl << endl;
  106. BMP24.read((char*)header, header_size); /// Odczytanie nagłówka
  107. if(header[0] != 'B' || header[1] != 'M') /// Potwierdza autentycznosc bitmapy
  108. {
  109. cout << "Blad. Plik zrodlowy nie jest bitmapa." << endl;
  110. system("pause");
  111. exit(0);
  112. }
  113. if(header[28] != 24)
  114. {
  115. cout << "Blad. Bitmapa nie ma formatu 24 bitowego." << endl;
  116. system("pause");
  117. exit(0);
  118. }
  119. cout << "Dane naglowka zostaly pobrane." << endl << endl;
  120.  
  121. cout << "Nastepuje pobieranie cech bitmapy." << endl << endl; /// Pobiera cechy bitmapy
  122. BMP_code(header+34, (uint8_t*)&sourcefilesize, DWORD);
  123. BMP_code(header+18, (uint8_t*)&width, DWORD);
  124. BMP_code(header+22, (uint8_t*)&height, DWORD);
  125.  
  126. sourcedatasize = width*height*3;
  127. sourcepadding = (sourcefilesize-sourcedatasize)/height;
  128.  
  129. cout << "Nastepuje pobieranie pikseli bitmapy." << endl << endl;
  130. sourcedata = new uint8_t[sourcedatasize];
  131. for(uint32_t a = 0; a<height; a++) /// Wczytuje piksele pomijajac jednoczesnie wypelnienie do wielokrotnosci 4
  132. {
  133. BMP24.read((char*)(sourcedata+a*width*3), width*3);
  134. BMP24.seekg(sourcepadding, BMP24.cur);
  135. }
  136. BMP24.close();
  137.  
  138. cout << "Dane pikselow bitmapy zostaly pobrane." << endl << endl;
  139.  
  140. destdatasize = sourcedatasize/3;
  141. destdata = new uint8_t[destdatasize];
  142.  
  143. cout << "Nastepuje pobranie danych palety kolorow." << endl << endl;
  144. szablon_palety.open("template.plt", ifstream::in | ifstream::binary); /// Gotowa paleta jest otwierana z pliku
  145. if(!szablon_palety.is_open())
  146. {
  147. cout << "Blad. Brak pliku zawierającego domyslna palete." << endl;
  148. delete [] sourcedata;
  149. system("pause");
  150. exit(0);
  151. }
  152. cout << "Paleta kolorow zostala wczytana." << endl << endl;
  153.  
  154. szablon_palety.read((char*)palette, palette_size);
  155. szablon_palety.close();
  156.  
  157. cout << "Uwaga. Nastepuje konwersja pikseli z 24 bitow do 8 bitow." << endl << endl;
  158. for(uint32_t a = 0; a<destdatasize; a++) destdata[a] = uint8_t(GetColorIndex(sourcedata[a*3],sourcedata[a*3+1],sourcedata[a*3+2], palette)); /// Klucz programu, konwersja
  159. cout << "Piksele bitmapy 24 bitowej zostaly przekonwertowane na format 8 bitowy." << endl << endl;
  160.  
  161. destdatapadding = 4-(width%4);
  162. if(destdatapadding == 4) destdatapadding = 0; /// Oblicza wypelnienie dla 8 bitow
  163.  
  164. uint32_t dword;
  165. uint16_t word;
  166.  
  167. /// Uzupelnianie naglowka
  168. cout << "Ustawianie naglowka dla formatu 8 bitowego." << endl << endl;
  169. dword = (width+destdatapadding)*height+54+1024;
  170. BMP_code((uint8_t*)&dword, header+2, DWORD);
  171.  
  172. dword = 1024+54;
  173. BMP_code((uint8_t*)&dword, header+10, DWORD);
  174.  
  175. word = 8;
  176. BMP_code((uint8_t*)&word, header+28, WORD);
  177.  
  178. dword = (width+destdatapadding)*height;
  179. BMP_code((uint8_t*)&dword, header+34, DWORD);
  180.  
  181. cout << "Tworzenie pliku koncowego pod nazwa outcome.bmp" << endl << endl;
  182. BMP8.open("outcome.bmp", ofstream::out | ofstream::binary);
  183. if(!BMP8.is_open())
  184. {
  185. cout << "Blad. Nie udalo sie utworzyc pliku koncowego." << endl;
  186. delete [] sourcedata;
  187. delete [] destdata;
  188. system("pause");
  189. exit(0);
  190. }
  191. cout << "Tworzenie powiodlo sie. Nastepuje zapisywanie danych." << endl << endl;
  192.  
  193. BMP8.write((char*)header, header_size);
  194. BMP8.write((char*)palette, palette_size);
  195. for(uint32_t a = 0; a<height; a++) /// Wypelnia piksele
  196. {
  197. BMP8.write((char*)(destdata+a*width), width); /// Piksele
  198. for(uint32_t b = 0; b<destdatapadding; b++) BMP8 << '\0'; /// Wypelnienie
  199. }
  200. BMP8.close();
  201.  
  202. delete [] sourcedata;
  203. delete [] destdata;
  204.  
  205. cout << "Konwersja ukonczona." << endl << endl;
  206. system("pause");
  207.  
  208. return 0;
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement