Ticket #1999: patch_bootsplash_20080406.diff
File patch_bootsplash_20080406.diff, 7.5 KB (added by , 16 years ago) |
---|
-
src/tools/generate_boot_screen.cpp
5 5 * Authors: 6 6 * Artur Wyszynski <harakash@gmail.com> 7 7 * Stephan Aßmus <superstippi@gmx.de> 8 * Philippe Saint-Pierre <stpere@gmail.com> 8 9 */ 9 10 10 11 //! Haiku boot splash image generator/converter … … 13 14 #include <png.h> 14 15 #include <string> 15 16 #include <stdarg.h> 17 #include <stdint.h> 16 18 17 19 // TODO: Generate the single optimal palette for all three images, 18 20 // store palette versions of these images as well, so that they are … … 21 23 22 24 23 25 FILE* sOutput = NULL; 26 int sOffset = 0; 24 27 25 26 28 static void 27 29 error(const char *s, ...) 28 30 { … … 120 122 121 123 122 124 static void 125 newLineIfRequired() 126 { 127 sOffset++; 128 if (sOffset%12 == 0) 129 { 130 fprintf(sOutput, "\n\t"); 131 } 132 } 133 134 135 static void 123 136 writeHeader(const char* baseName, int width, int height, png_bytep* rowPtrs) 124 137 { 125 138 fprintf(sOutput, "static const uint16 %sWidth = %d;\n", baseName, width); 126 139 fprintf(sOutput, "static const uint16 %sHeight = %d;\n", baseName, height); 127 140 fprintf(sOutput, "#ifndef __BOOTSPLASH_KERNEL__\n"); 128 fprintf(sOutput, "static const RLE_element %sCompressedImage[] = {\n\t", 141 142 int buffer[128]; 143 // buffer[0] stores count, buffer[1..127] holds the actual values 144 145 fprintf(sOutput, "static uint8 %sCompressedImage[] = {\n\t", 129 146 baseName); 130 147 131 int offset = 0; 132 int lastColor = -1; 133 int counter = 0; 134 for (int y = 0; y < height; y++) { 135 png_byte* row = rowPtrs[y]; 136 for (int x = 0; x < width * 3; x++) { 137 if (lastColor == row[x]) { 138 // if the currentColor is already being counted... 139 counter++; 140 } else { 141 // otherwise display what we had in memory, record that color 142 // and reset the counter... 143 if (lastColor != -1) { 144 offset++; 145 fprintf(sOutput, "{%d, 0x%02x}, ", counter, lastColor); 146 if (offset % 6 == 0) { 147 fprintf(sOutput, "\n\t"); 148 for (int c = 0; c < 3; c++) 149 { 150 // for each component i.e. R, G, B ... 151 // NOTE : I don't care much about performance at this step, decoding however... 152 int currentValue = rowPtrs[0][c]; 153 int count = 0; 154 155 // When bufferActive == true, we store the number rather than writing 156 // them directly; we use this to store numbers until we find a pair.. 157 bool bufferActive = false; 158 159 sOffset = 0; 160 161 for (int y = 0; y < height; y++) { 162 png_byte* row = rowPtrs[y]; 163 for (int x = c; x < width * 3; x += 3) { 164 if (row[x] == currentValue) { 165 if (bufferActive) { 166 bufferActive = false; 167 count = 2; 168 if (buffer[0] > 1) { 169 fprintf (sOutput, "%d, ", 170 128 + buffer[0] - 1); 171 newLineIfRequired(); 172 for (int i = 1; i < buffer[0] ; i++) { 173 fprintf( sOutput, "0x%02x, ", 174 buffer[i] ); 175 newLineIfRequired(); 176 } 177 } 178 } else { 179 count++; 180 if (count == 127) { 181 fprintf (sOutput, "127, "); 182 newLineIfRequired(); 183 fprintf (sOutput, "0x%02x, ", currentValue); 184 newLineIfRequired(); 185 count = 0; 186 } 148 187 } 188 } else { 189 if (bufferActive) { 190 if (buffer[0] == 127) { 191 // we don't have enough room, 192 // flush the buffer 193 fprintf (sOutput, "%d, ", 194 128 + buffer[0] - 1); 195 newLineIfRequired(); 196 for (int i = 1; i < buffer[0] ; i++) { 197 fprintf( sOutput, "0x%02x, ", 198 buffer[i] ); 199 newLineIfRequired(); 200 } 201 buffer[0] = 0; 202 } 203 buffer[0]++; 204 buffer[ buffer[0] ] = row[x]; 205 } else if (count > 0) { 206 buffer[0] = 1; 207 buffer[1] = row[x]; 208 bufferActive = true; 209 if (count > 1) { 210 fprintf (sOutput, "%d, ", count); 211 newLineIfRequired(); 212 fprintf (sOutput, "0x%02x, ", 213 currentValue); 214 newLineIfRequired(); 215 } 216 } 217 currentValue = row[x]; 149 218 } 150 lastColor = row[x];151 counter = 1;152 219 } 153 154 if (x == width * 3 - 1 && y == height - 1) { 155 // we have reach the end 156 fprintf(sOutput, "{%d, 0x%02x}\n};\n\n", counter, row[x]); 157 offset++; 158 break; 220 } 221 if (bufferActive) { 222 // I could have written 127 + buffer[0], but I think this is more readable... 223 fprintf (sOutput, "%d, ", 128 + buffer[0] - 1); 224 newLineIfRequired(); 225 for (int i = 1; i < buffer[0] ; i++) { 226 fprintf( sOutput, "0x%02x, ", buffer[i] ); 227 newLineIfRequired(); 159 228 } 229 } else { 230 fprintf(sOutput, "%d, 0x%02x, ", count, currentValue); 231 newLineIfRequired(); 232 } 233 // we put a ending zero, just to indicate end of channel 234 fprintf(sOutput, "0"); 235 if (c != 2) { 236 fprintf(sOutput, ","); 160 237 } 238 fprintf(sOutput, "\n\t"); 161 239 } 162 fprintf(sOutput, " static const uint32 %sSize = %d;\n", baseName, offset);240 fprintf(sOutput, "};\n"); 163 241 fprintf(sOutput, "#endif\n\n"); 164 242 } 165 243 … … 232 310 fprintf(sOutput, "static const int32 kSplashIconsPlacementY = %d;\n\n", 233 311 iconPlacementY); 234 312 235 fprintf(sOutput, "struct RLE_element \n{\n\tuint16 count; \n\tuint8 "236 "colorComponent;\n};\n\n");237 238 313 parseImage(argv[1], "kSplashLogo"); 239 314 parseImage(argv[4], "kSplashIcons"); 240 315 -
src/system/boot/platform/bios_ia32/video.cpp
796 796 797 797 798 798 static void 799 uncompress_RLE(const RLE_element *compressed, uint8 *uncompressed, uint32 size)799 uncompress_RLE(const uint8 compressed[], uint8 *uncompressed) 800 800 { 801 uint32 cursor = 0; 802 for (uint32 i = 0; i < size; i++) { 803 memset(uncompressed + cursor, compressed[i].colorComponent, 804 compressed[i].count); 805 cursor += compressed[i].count; 806 } 801 uint32 cursorUncompressed = 0; 802 uint32 cursorCompressed = 0; 803 uint8 count = 0; 804 uint8 item = 0; 805 int i = 0; 806 for (uint8 c = 0; c < 3; c++) { 807 // for Red channel, then Green, then finally Blue... 808 cursorUncompressed = c; 809 while (compressed[ cursorCompressed ]) { 810 // at the end of the channel there is a stopper 0, so the loop will end... 811 // (ref: generate_boot_screen.cpp) 812 count = compressed[ cursorCompressed++ ]; 813 if (count < 128) { 814 // regular run, repeat "item" "count" times... 815 item = compressed[ cursorCompressed++ ]; 816 for (i = count - 1; i >= 0; --i) { 817 uncompressed[ cursorUncompressed ] = item; 818 cursorUncompressed += 3; 819 } 820 } else { 821 // enumeration, just write the next "count" items as is... 822 count = count - 128; 823 for (i = count - 1; i >= 0; --i) { 824 uncompressed[ cursorUncompressed ] = compressed[ cursorCompressed++ ]; 825 cursorUncompressed += 3; 826 } 827 } 828 } 829 // the current position of compressed[cursor] is the end of channel, we skip it... 830 cursorCompressed++; 831 } 807 832 } 808 833 809 834 // #pragma mark - … … 884 909 * kSplashLogoHeight * 3); 885 910 if (uncompressedLogo == NULL) 886 911 return; 887 uncompress_RLE(kSplashLogoCompressedImage, uncompressedLogo, 888 kSplashLogoSize); 912 uncompress_RLE(kSplashLogoCompressedImage, uncompressedLogo); 889 913 890 914 // TODO: support indexed versions of the images! 891 915 … … 911 935 * kSplashIconsHeight * 3); 912 936 if (gKernelArgs.boot_splash == NULL) 913 937 return; 914 uncompress_RLE(kSplashIconsCompressedImage, gKernelArgs.boot_splash, 915 kSplashIconsSize); 938 uncompress_RLE(kSplashIconsCompressedImage, gKernelArgs.boot_splash ); 916 939 917 940 // render initial (grayed out) icons 918 941 // the grayed out version is the lower half of the icons image