image_importer_raw.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*******************************************************************************************
  2. *
  3. * raygui - image raw importer
  4. *
  5. * DEPENDENCIES:
  6. * raylib 4.0 - Windowing/input management and drawing.
  7. * raygui 3.0 - Immediate-mode GUI controls.
  8. *
  9. * COMPILATION (Windows - MinGW):
  10. * gcc -o $(NAME_PART).exe $(FILE_NAME) -I../../src -lraylib -lopengl32 -lgdi32 -std=c99
  11. *
  12. * LICENSE: zlib/libpng
  13. *
  14. * Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
  15. *
  16. **********************************************************************************************/
  17. #include "raylib.h"
  18. #define RAYGUI_IMPLEMENTATION
  19. #include "../../src/raygui.h"
  20. #include <string.h> // Required for: strcpy()
  21. #include <stdlib.h> // Required for: atoi()
  22. #include <math.h> // Required for: round()
  23. //------------------------------------------------------------------------------------
  24. // Program main entry point
  25. //------------------------------------------------------------------------------------
  26. int main()
  27. {
  28. // Initialization
  29. //---------------------------------------------------------------------------------------
  30. const int screenWidth = 800;
  31. const int screenHeight = 600;
  32. InitWindow(screenWidth, screenHeight, "raygui - image raw importer");
  33. Texture2D texture = { 0 };
  34. // GUI controls initialization
  35. //----------------------------------------------------------------------------------
  36. Vector2 windowOffset = { screenWidth/2 - 200/2, screenHeight/2 - 465/2 };
  37. bool importWindowActive = false;
  38. int widthValue = 0;
  39. bool widthEditMode = false;
  40. int heightValue = 0;
  41. bool heightEditMode = false;
  42. int pixelFormatActive = 0;
  43. char *pixelFormatTextList[8] = { "CUSTOM", "GRAYSCALE", "GRAY ALPHA", "R5G6B5", "R8G8B8", "R5G5B5A1", "R4G4B4A4", "R8G8B8A8" };
  44. int channelsActive = 3;
  45. char *channelsTextList[4] = { "1", "2", "3", "4" };
  46. int bitDepthActive = 0;
  47. char *bitDepthTextList[3] = { "8", "16", "32" };
  48. int headerSizeValue = 0;
  49. bool headerSizeEditMode = false;
  50. //----------------------------------------------------------------------------------
  51. // Image file info
  52. int dataSize = 0;
  53. char fileNamePath[256] = "\0";
  54. char fileName[64] = "\0";
  55. bool btnLoadPressed = false;
  56. bool imageLoaded = false;
  57. float imageScale = 1.0f;
  58. SetTargetFPS(60);
  59. //--------------------------------------------------------------------------------------
  60. // Main game loop
  61. while (!WindowShouldClose()) // Detect window close button or ESC key
  62. {
  63. // Update
  64. //----------------------------------------------------------------------------------
  65. // Check if a file is dropped
  66. if (IsFileDropped())
  67. {
  68. FilePathList droppedFiles = LoadDroppedFiles();
  69. // Check file extensions for drag-and-drop
  70. if ((droppedFiles.count == 1) && IsFileExtension(droppedFiles.paths[0], ".raw"))
  71. {
  72. FILE *imageFile = fopen(droppedFiles.paths[0], "rb");
  73. fseek(imageFile, 0L, SEEK_END);
  74. dataSize = ftell(imageFile);
  75. fclose(imageFile);
  76. // NOTE: Returned string is just a pointer to droppedFiles[0],
  77. // we need to make a copy of that data somewhere else: fileName
  78. strcpy(fileNamePath, droppedFiles.paths[0]);
  79. strcpy(fileName, GetFileName(droppedFiles.paths[0]));
  80. // Try to guess possible raw values
  81. // Let's assume image is square, RGBA, 8 bit per channel
  82. widthValue = round(sqrt(dataSize/4));
  83. heightValue = widthValue;
  84. headerSizeValue = dataSize - widthValue*heightValue*4;
  85. if (headerSizeValue < 0) headerSizeValue = 0;
  86. importWindowActive = true;
  87. }
  88. UnloadDroppedFiles(droppedFiles);
  89. }
  90. // Check if load button has been pressed
  91. if (btnLoadPressed)
  92. {
  93. // Depending on channels and bit depth, select correct pixel format
  94. if ((widthValue != 0) && (heightValue != 0))
  95. {
  96. int format = -1;
  97. if (pixelFormatActive == 0)
  98. {
  99. int channels = atoi(channelsTextList[channelsActive]);
  100. int bpp = atoi(bitDepthTextList[bitDepthActive]);
  101. // Select correct format depending on channels and bpp
  102. if (bpp == 8)
  103. {
  104. if (channels == 1) format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
  105. else if (channels == 2) format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
  106. else if (channels == 3) format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
  107. else if (channels == 4) format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
  108. }
  109. else if (bpp == 32)
  110. {
  111. if (channels == 1) format = PIXELFORMAT_UNCOMPRESSED_R32;
  112. else if (channels == 2) TraceLog(LOG_WARNING, "Channel bit-depth not supported!");
  113. else if (channels == 3) format = PIXELFORMAT_UNCOMPRESSED_R32G32B32;
  114. else if (channels == 4) format = PIXELFORMAT_UNCOMPRESSED_R32G32B32A32;
  115. }
  116. else if (bpp == 16) TraceLog(LOG_WARNING, "Channel bit-depth not supported!");
  117. }
  118. else format = pixelFormatActive;
  119. if (format != -1)
  120. {
  121. Image image = LoadImageRaw(fileNamePath, widthValue, heightValue, format, headerSizeValue);
  122. texture = LoadTextureFromImage(image);
  123. UnloadImage(image);
  124. importWindowActive = false;
  125. btnLoadPressed = false;
  126. if (texture.id > 0)
  127. {
  128. imageLoaded = true;
  129. imageScale = (float)(screenHeight - 100)/texture.height;
  130. }
  131. }
  132. }
  133. }
  134. if (imageLoaded) imageScale += (float)GetMouseWheelMove(); // Image scale control
  135. //----------------------------------------------------------------------------------
  136. // Draw
  137. //----------------------------------------------------------------------------------
  138. BeginDrawing();
  139. ClearBackground(GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR)));
  140. if (texture.id != 0)
  141. {
  142. DrawTextureEx(texture, (Vector2){ screenWidth/2 - texture.width*imageScale/2, screenHeight/2 - texture.height*imageScale/2 }, 0, imageScale, WHITE);
  143. DrawText(TextFormat("SCALE x%.0f", imageScale), 20, screenHeight - 40, 20, GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)));
  144. }
  145. else DrawText("drag & drop RAW image file", 320, 180, 10, GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)));
  146. // raygui: controls drawing
  147. //----------------------------------------------------------------------------------
  148. if (importWindowActive)
  149. {
  150. importWindowActive = !GuiWindowBox((Rectangle){ windowOffset.x + 0, windowOffset.y + 0, 200, 465 }, "Image RAW Import Options");
  151. GuiLabel((Rectangle){ windowOffset.x + 10, windowOffset.y + 30, 65, 20 }, "Import file:");
  152. GuiLabel((Rectangle){ windowOffset.x + 85, windowOffset.y + 30, 75, 20 }, fileName);
  153. GuiLabel((Rectangle){ windowOffset.x + 10, windowOffset.y + 50, 65, 20 }, "File size:");
  154. GuiLabel((Rectangle){ windowOffset.x + 85, windowOffset.y + 50, 75, 20 }, TextFormat("%i bytes", dataSize));
  155. GuiGroupBox((Rectangle){ windowOffset.x + 10, windowOffset.y + 85, 180, 80 }, "Resolution");
  156. GuiLabel((Rectangle){ windowOffset.x + 20, windowOffset.y + 100, 33, 25 }, "Width:");
  157. if (GuiValueBox((Rectangle){ windowOffset.x + 60, windowOffset.y + 100, 80, 25 }, NULL, &widthValue, 0, 8192, widthEditMode)) widthEditMode = !widthEditMode;
  158. GuiLabel((Rectangle){ windowOffset.x + 145, windowOffset.y + 100, 30, 25 }, "pixels");
  159. GuiLabel((Rectangle){ windowOffset.x + 20, windowOffset.y + 130, 33, 25 }, "Height:");
  160. if (GuiValueBox((Rectangle){ windowOffset.x + 60, windowOffset.y + 130, 80, 25 }, NULL, &heightValue, 0, 8192, heightEditMode)) heightEditMode = !heightEditMode;
  161. GuiLabel((Rectangle){ windowOffset.x + 145, windowOffset.y + 130, 30, 25 }, "pixels");
  162. GuiGroupBox((Rectangle){ windowOffset.x + 10, windowOffset.y + 180, 180, 160 }, "Pixel Format");
  163. GuiComboBox((Rectangle){ windowOffset.x + 20, windowOffset.y + 195, 160, 25 }, TextJoin(pixelFormatTextList, 8, ";"), &pixelFormatActive);
  164. GuiLine((Rectangle){ windowOffset.x + 20, windowOffset.y + 220, 160, 20 }, NULL);
  165. if (pixelFormatActive != 0) GuiDisable();
  166. GuiLabel((Rectangle){ windowOffset.x + 20, windowOffset.y + 235, 50, 20 }, "Channels:");
  167. GuiToggleGroup((Rectangle){ windowOffset.x + 20, windowOffset.y + 255, 156/4, 25 }, TextJoin(channelsTextList, 4, ";"), &channelsActive);
  168. GuiLabel((Rectangle){ windowOffset.x + 20, windowOffset.y + 285, 50, 20 }, "Bit Depth:");
  169. GuiToggleGroup((Rectangle){ windowOffset.x + 20, windowOffset.y + 305, 160/3, 25 }, TextJoin(bitDepthTextList, 3, ";"), &bitDepthActive);
  170. GuiEnable();
  171. GuiGroupBox((Rectangle){ windowOffset.x + 10, windowOffset.y + 355, 180, 50 }, "Header");
  172. GuiLabel((Rectangle){ windowOffset.x + 25, windowOffset.y + 370, 27, 25 }, "Size:");
  173. if (GuiValueBox((Rectangle){ windowOffset.x + 55, windowOffset.y + 370, 85, 25 }, NULL, &headerSizeValue, 0, 10000, headerSizeEditMode)) headerSizeEditMode = !headerSizeEditMode;
  174. GuiLabel((Rectangle){ windowOffset.x + 145, windowOffset.y + 370, 30, 25 }, "bytes");
  175. btnLoadPressed = GuiButton((Rectangle){ windowOffset.x + 10, windowOffset.y + 420, 180, 30 }, "Import RAW");
  176. }
  177. //----------------------------------------------------------------------------------
  178. EndDrawing();
  179. //----------------------------------------------------------------------------------
  180. }
  181. // De-Initialization
  182. //--------------------------------------------------------------------------------------
  183. if (texture.id != 0) UnloadTexture(texture);
  184. CloseWindow(); // Close window and OpenGL context
  185. //--------------------------------------------------------------------------------------
  186. return 0;
  187. }