| 1 11 package org.eclipse.swt.tools.internal; 12 13 import java.io.*; 14 import java.util.*; 15 16 24 public class IconExe { 25 26 51 public static void main(String [] args) throws Exception { 52 if (args.length < 2) { 53 System.err.println("Usage: IconExe <windows executable> <ico file>"); 54 return; 55 } 56 ImageLoader loader = new ImageLoader(); 57 58 List images = new ArrayList(); 59 for (int i = 1; i < args.length; i++) { 60 try { 61 ImageData[] current = loader.load(args[i]); 63 for (int j = 0; j < current.length; j++) { 64 images.add(current[j]); 65 } 66 } catch (RuntimeException e) { 67 } 69 } 70 ImageData[] data = new ImageData[images.size()]; 71 data = (ImageData[]) images.toArray(data); 72 73 int nMissing = unloadIcons(args[0], data); 74 if (nMissing != 0) 75 System.err.println("Error - " + nMissing + " icon(s) not replaced in " + args[0] + " using " + args[1]); 76 } 77 78 79 80 94 static ImageData[] loadIcons(String program) throws FileNotFoundException, IOException { 95 RandomAccessFile raf = new RandomAccessFile(program, "r"); 96 IconExe iconExe = new IconExe(); 97 IconResInfo[] iconInfo = iconExe.getIcons(raf); 98 ImageData[] data = new ImageData[iconInfo.length]; 99 for (int i = 0; i < data.length; i++) data[i] = iconInfo[i].data; 100 raf.close(); 101 return data; 102 } 103 104 134 static int unloadIcons(String program, ImageData[] icons) throws FileNotFoundException, IOException { 135 RandomAccessFile raf = new RandomAccessFile(program, "rw"); 136 IconExe iconExe = new IconExe(); 137 IconResInfo[] iconInfo = iconExe.getIcons(raf); 138 int cnt = 0; 139 for (int i = 0; i < iconInfo.length; i++) { 140 for (int j = 0; j < icons.length; j++) { 141 if (icons[j] == null) 142 continue; 143 if (iconInfo[i].data.width == icons[j].width && iconInfo[i].data.height == icons[j].height && iconInfo[i].data.depth == icons[j].depth) { 144 raf.seek(iconInfo[i].offset); 145 unloadIcon(raf, icons[j]); 146 cnt++; 147 break; 148 } 149 } 150 } 151 raf.close(); 152 return iconInfo.length - cnt; 153 } 154 155 public static final String VERSION = "20050124"; 156 157 static final boolean DEBUG = false; 158 public static class IconResInfo { 159 ImageData data; 160 int offset; 161 int size; 162 } 163 164 IconResInfo[] iconInfo = null; 165 int iconCnt; 166 167 IconResInfo[] getIcons(RandomAccessFile raf) throws IOException { 168 iconInfo = new IconResInfo[4]; 169 iconCnt = 0; 170 IMAGE_DOS_HEADER imageDosHeader = new IMAGE_DOS_HEADER(); 171 read(raf, imageDosHeader); 172 if (imageDosHeader.e_magic != IMAGE_DOS_SIGNATURE) return null; 173 int imageNtHeadersOffset = imageDosHeader.e_lfanew; 174 raf.seek(imageNtHeadersOffset); 175 IMAGE_NT_HEADERS imageNtHeaders = new IMAGE_NT_HEADERS(); 176 read(raf, imageNtHeaders); 177 if (imageNtHeaders.Signature != IMAGE_NT_SIGNATURE) return null; 178 179 int resourcesRVA = imageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; 181 if (resourcesRVA == 0) return null; 182 if (DEBUG) System.out.println("* Resources (RVA= "+resourcesRVA+")"); 183 IMAGE_SECTION_HEADER imageSectionHeader = new IMAGE_SECTION_HEADER(); 184 int firstSectionOffset = imageNtHeadersOffset + IMAGE_NT_HEADERS.FIELD_OFFSET_OptionalHeader + imageNtHeaders.FileHeader.SizeOfOptionalHeader; 185 raf.seek(firstSectionOffset); 186 boolean found = false; 187 for (int i = 0; i < imageNtHeaders.FileHeader.NumberOfSections; i++) { 188 read(raf, imageSectionHeader); 189 if (resourcesRVA >= imageSectionHeader.VirtualAddress && resourcesRVA < imageSectionHeader.VirtualAddress + imageSectionHeader.Misc_VirtualSize) { 190 found = true; 192 break; 193 } 194 } 195 if (!found) return null; 196 int delta = imageSectionHeader.VirtualAddress - imageSectionHeader.PointerToRawData; 197 int imageResourceDirectoryOffset = resourcesRVA - delta; 198 dumpResourceDirectory(raf, imageResourceDirectoryOffset, imageResourceDirectoryOffset, delta, 0, 0, false); 199 if (iconCnt < iconInfo.length) { 200 IconResInfo[] newArray = new IconResInfo[iconCnt]; 201 System.arraycopy(iconInfo, 0, newArray, 0, iconCnt); 202 iconInfo = newArray; 203 } 204 return iconInfo; 205 } 206 207 void dumpResourceDirectory(RandomAccessFile raf, int imageResourceDirectoryOffset, int resourceBase, int delta, int type, int level, boolean rt_icon_root) throws IOException { 208 if (DEBUG) System.out.println("** LEVEL "+level); 209 210 IMAGE_RESOURCE_DIRECTORY imageResourceDirectory = new IMAGE_RESOURCE_DIRECTORY(); 211 raf.seek(imageResourceDirectoryOffset); 212 read(raf, imageResourceDirectory); 213 214 if (DEBUG) { 215 String sType = ""+type; 216 if (level == 1) { 218 System.out.println("___________________________"); 219 if (type == RT_ICON) sType = "RT_ICON"; 220 if (type == RT_GROUP_ICON) sType = "RT_GROUP_ICON"; 221 } 222 System.out.println("Resource Directory ["+sType+"]"+" (Named "+imageResourceDirectory.NumberOfNamedEntries+", ID "+imageResourceDirectory.NumberOfIdEntries+")"); 223 } 224 int IRDE_StartOffset = imageResourceDirectoryOffset + IMAGE_RESOURCE_DIRECTORY.SIZEOF; 225 IMAGE_RESOURCE_DIRECTORY_ENTRY[] imageResourceDirectoryEntries = new IMAGE_RESOURCE_DIRECTORY_ENTRY[imageResourceDirectory.NumberOfIdEntries]; 226 for (int i = 0; i < imageResourceDirectoryEntries.length; i++) { 227 imageResourceDirectoryEntries[i] = new IMAGE_RESOURCE_DIRECTORY_ENTRY(); 228 read(raf, imageResourceDirectoryEntries[i]); 229 } 230 for (int i = 0; i < imageResourceDirectoryEntries.length; i++) { 231 if (imageResourceDirectoryEntries[i].DataIsDirectory) { 232 dumpResourceDirectory(raf, imageResourceDirectoryEntries[i].OffsetToDirectory + resourceBase, resourceBase, delta, imageResourceDirectoryEntries[i].Id, level + 1, rt_icon_root ? true : type == RT_ICON); 233 } else { 234 IMAGE_RESOURCE_DIRECTORY_ENTRY irde = imageResourceDirectoryEntries[i]; 237 IMAGE_RESOURCE_DATA_ENTRY data = new IMAGE_RESOURCE_DATA_ENTRY(); 238 raf.seek(imageResourceDirectoryEntries[i].OffsetToData + resourceBase); 239 read(raf, data); 240 if (DEBUG) System.out.println("Resource Id "+irde.Id+" Data Offset RVA "+data.OffsetToData+", Size "+data.Size); 241 if (rt_icon_root) { 242 if (DEBUG) System.out.println("iconcnt "+iconCnt+" |"+iconInfo.length); 243 iconInfo[iconCnt] = new IconResInfo(); 244 iconInfo[iconCnt].data = parseIcon(raf, data.OffsetToData - delta, data.Size); 245 iconInfo[iconCnt].offset = data.OffsetToData - delta; 246 iconInfo[iconCnt].size = data.Size; 247 iconCnt++; 248 if (iconCnt == iconInfo.length) { 249 IconResInfo[] newArray = new IconResInfo[iconInfo.length + 4]; 250 System.arraycopy(iconInfo, 0, newArray, 0, iconInfo.length); 251 iconInfo = newArray; 252 } 253 } 254 } 255 } 256 } 257 258 static ImageData parseIcon(RandomAccessFile raf, int offset, int size) throws IOException { 259 raf.seek(offset); 260 BITMAPINFO bitmapInfo = new BITMAPINFO(); 261 read(raf, bitmapInfo); 262 bitmapInfo.bmiHeader.biHeight /= 2; 263 int width = bitmapInfo.bmiHeader.biWidth; 264 int height = bitmapInfo.bmiHeader.biHeight; 265 int depth = bitmapInfo.bmiHeader.biBitCount; 266 267 PaletteData palette = loadPalette(bitmapInfo.bmiHeader, raf); 268 byte[] shapeData = loadData(bitmapInfo.bmiHeader, raf); 269 bitmapInfo.bmiHeader.biBitCount = 1; 270 byte[] maskData = loadData(bitmapInfo.bmiHeader, raf); 271 maskData = convertPad(maskData, width, height, 1, 4, 2); 272 bitInvertData(maskData, 0, maskData.length); 273 return ImageData.internal_new( 274 width, 275 height, 276 depth, 277 palette, 278 4, 279 shapeData, 280 2, 281 maskData, 282 null, 283 -1, 284 -1, 285 SWT.IMAGE_ICO, 286 0, 287 0, 288 0, 289 0); 290 } 291 292 static byte[] bitInvertData(byte[] data, int startIndex, int endIndex) { 293 for (int i = startIndex; i < endIndex; i++) { 295 data[i] = (byte)(255 - data[i - startIndex]); 296 } 297 return data; 298 } 299 300 static final byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) { 301 if (pad == newPad) return data; 302 int stride = (width * depth + 7) / 8; 303 int bpl = (stride + (pad - 1)) / pad * pad; 304 int newBpl = (stride + (newPad - 1)) / newPad * newPad; 305 byte[] newData = new byte[height * newBpl]; 306 int srcIndex = 0, destIndex = 0; 307 for (int y = 0; y < height; y++) { 308 System.arraycopy(data, srcIndex, newData, destIndex, newBpl); 309 srcIndex += bpl; 310 destIndex += newBpl; 311 } 312 return newData; 313 } 314 static PaletteData loadPalette(BITMAPINFOHEADER bih, RandomAccessFile raf) throws IOException { 315 int depth = bih.biBitCount; 316 if (depth <= 8) { 317 int numColors = bih.biClrUsed; 318 if (numColors == 0) { 319 numColors = 1 << depth; 320 } else { 321 if (numColors > 256) 322 numColors = 256; 323 } 324 byte[] buf = new byte[numColors * 4]; 325 raf.read(buf); 326 return paletteFromBytes(buf, numColors); 327 } 328 if (depth == 16) return new PaletteData(0x7C00, 0x3E0, 0x1F); 329 if (depth == 24) return new PaletteData(0xFF, 0xFF00, 0xFF0000); 330 return new PaletteData(0xFF00, 0xFF0000, 0xFF000000); 331 } 332 static PaletteData paletteFromBytes(byte[] bytes, int numColors) { 333 int bytesOffset = 0; 334 RGB[] colors = new RGB[numColors]; 335 for (int i = 0; i < numColors; i++) { 336 colors[i] = new RGB(bytes[bytesOffset + 2] & 0xFF, 337 bytes[bytesOffset + 1] & 0xFF, 338 bytes[bytesOffset] & 0xFF); 339 bytesOffset += 4; 340 } 341 return new PaletteData(colors); 342 } 343 static byte[] loadData(BITMAPINFOHEADER bih, RandomAccessFile raf) throws IOException { 344 int stride = (bih.biWidth * bih.biBitCount + 7) / 8; 345 stride = (stride + 3) / 4 * 4; byte[] data = loadData(bih, raf, stride); 347 flipScanLines(data, stride, bih.biHeight); 348 return data; 349 } 350 static void flipScanLines(byte[] data, int stride, int height) { 351 int i1 = 0; 352 int i2 = (height - 1) * stride; 353 for (int i = 0; i < height / 2; i++) { 354 for (int index = 0; index < stride; index++) { 355 byte b = data[index + i1]; 356 data[index + i1] = data[index + i2]; 357 data[index + i2] = b; 358 } 359 i1 += stride; 360 i2 -= stride; 361 } 362 } 363 static byte[] loadData(BITMAPINFOHEADER bih, RandomAccessFile raf, int stride) throws IOException { 364 int dataSize = bih.biHeight * stride; 365 byte[] data = new byte[dataSize]; 366 int cmp = bih.biCompression; 367 if (cmp == 0) { raf.read(data); 369 } else { 370 if (DEBUG) System.out.println("ICO cannot be compressed?"); 371 } 372 return data; 373 } 374 375 static void unloadIcon(RandomAccessFile raf, ImageData icon) throws IOException { 376 int sizeImage = (((icon.width * icon.depth + 31) / 32 * 4) + 377 ((icon.width + 31) / 32 * 4)) * icon.height; 378 write4(raf, BMPHeaderFixedSize); 379 write4(raf, icon.width); 380 write4(raf, icon.height * 2); 381 writeU2(raf, 1); 382 writeU2(raf, icon.depth); 383 write4(raf, 0); 384 write4(raf, sizeImage); 385 write4(raf, 0); 386 write4(raf, 0); 387 write4(raf, icon.palette.colors != null ? icon.palette.colors.length : 0); 388 write4(raf, 0); 389 390 byte[] rgbs = paletteToBytes(icon.palette); 391 raf.write(rgbs); 392 unloadShapeData(raf, icon); 393 unloadMaskData(raf, icon); 394 } 395 static byte[] paletteToBytes(PaletteData pal) { 396 int n = pal.colors == null ? 0 : (pal.colors.length < 256 ? pal.colors.length : 256); 397 byte[] bytes = new byte[n * 4]; 398 int offset = 0; 399 for (int i = 0; i < n; i++) { 400 RGB col = pal.colors[i]; 401 bytes[offset] = (byte)col.blue; 402 bytes[offset + 1] = (byte)col.green; 403 bytes[offset + 2] = (byte)col.red; 404 offset += 4; 405 } 406 return bytes; 407 } 408 static void unloadMaskData(RandomAccessFile raf, ImageData icon) { 409 ImageData mask = icon.getTransparencyMask(); 410 int bpl = (icon.width + 7) / 8; 411 int pad = mask.scanlinePad; 412 int srcBpl = (bpl + pad - 1) / pad * pad; 413 int destBpl = (bpl + 3) / 4 * 4; 414 byte[] buf = new byte[destBpl]; 415 int offset = (icon.height - 1) * srcBpl; 416 byte[] data = mask.data; 417 try { 418 for (int i = 0; i < icon.height; i++) { 419 System.arraycopy(data, offset, buf, 0, bpl); 420 bitInvertData(buf, 0, bpl); 421 raf.write(buf, 0, destBpl); 422 offset -= srcBpl; 423 } 424 } catch (IOException e) { 425 SWT.error(SWT.ERROR_IO, e); 426 } 427 } 428 static void unloadShapeData(RandomAccessFile raf, ImageData icon) { 429 int bpl = (icon.width * icon.depth + 7) / 8; 430 int pad = icon.scanlinePad; 431 int srcBpl = (bpl + pad - 1) / pad * pad; 432 int destBpl = (bpl + 3) / 4 * 4; 433 byte[] buf = new byte[destBpl]; 434 int offset = (icon.height - 1) * srcBpl; 435 byte[] data = icon.data; 436 try { 437 for (int i = 0; i < icon.height; i++) { 438 System.arraycopy(data, offset, buf, 0, bpl); 439 raf.write(buf, 0, destBpl); 440 offset -= srcBpl; 441 } 442 } catch (IOException e) { 443 SWT.error(SWT.ERROR_IO, e); 444 } 445 } 446 static boolean readIconGroup(RandomAccessFile raf, int offset, int size) throws IOException { 447 raf.seek(offset); 448 NEWHEADER newHeader = new NEWHEADER(); 449 read(raf, newHeader); 450 if (newHeader.ResType != RES_ICON) return false; 451 RESDIR[] resDir = new RESDIR[newHeader.ResCount]; 452 for (int i = 0; i < newHeader.ResCount; i++) { 453 resDir[i] = new RESDIR(); 454 read(raf, resDir[i]); 455 } 456 return true; 457 } 458 459 static void copyFile(String src, String dst) throws FileNotFoundException, IOException { 460 File srcFile = new File(src); 461 File dstFile = new File(dst); 462 FileInputStream in = new FileInputStream(srcFile); 463 FileOutputStream out = new FileOutputStream(dstFile); 464 int c; 465 while ((c = in.read()) != -1) out.write(c); 466 in.close(); 467 out.close(); 468 } 469 470 471 static final int IMAGE_DOS_SIGNATURE = 0x5a4d; 472 static final int IMAGE_NT_SIGNATURE = 0x00004550; 473 static final int IMAGE_DIRECTORY_ENTRY_RESOURCE = 2; 474 static final int RES_ICON = 1; 475 static final int RT_ICON = 3; 476 static final int RT_GROUP_ICON = 14; 477 static final int BMPHeaderFixedSize = 40; 478 479 public static class IMAGE_DOS_HEADER { 480 int e_magic; int e_cblp; int e_cp; int e_crlc; int e_cparhdr; int e_minalloc; int e_maxalloc; int e_ss; int e_sp; int e_csum; int e_ip; int e_cs; int e_lfarlc; int e_ovno; int[] e_res = new int[4]; int e_oemid; int e_oeminfo; int[] e_res2 = new int[10]; int e_lfanew; } 500 501 public static class IMAGE_FILE_HEADER { 502 int Machine; int NumberOfSections; int TimeDateStamp; int PointerToSymbolTable; int NumberOfSymbols; int SizeOfOptionalHeader; int Characteristics; } 510 511 public static class IMAGE_DATA_DIRECTORY { 512 int VirtualAddress; int Size; } 515 516 public static class IMAGE_OPTIONAL_HEADER { 517 int Magic; int MajorLinkerVersion; int MinorLinkerVersion; int SizeOfCode; int SizeOfInitializedData; int SizeOfUninitializedData; int AddressOfEntryPoint; int BaseOfCode; int BaseOfData; int ImageBase; int SectionAlignment; int FileAlignment; int MajorOperatingSystemVersion; int MinorOperatingSystemVersion; int MajorImageVersion; int MinorImageVersion; int MajorSubsystemVersion; int MinorSubsystemVersion; int Win32VersionValue; int SizeOfImage; int SizeOfHeaders; int CheckSum; int Subsystem; int DllCharacteristics; int SizeOfStackReserve; int SizeOfStackCommit; int SizeOfHeapReserve; int SizeOfHeapCommit; int LoaderFlags; int NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY[] DataDirectory = new IMAGE_DATA_DIRECTORY[16]; 548 } 549 public static class IMAGE_NT_HEADERS { 550 int Signature; IMAGE_FILE_HEADER FileHeader = new IMAGE_FILE_HEADER(); 552 IMAGE_OPTIONAL_HEADER OptionalHeader = new IMAGE_OPTIONAL_HEADER(); 553 final static int FIELD_OFFSET_OptionalHeader = 24; 554 } 555 556 public static class IMAGE_SECTION_HEADER { 557 int[] Name = new int[8]; int Misc_VirtualSize; int VirtualAddress; int SizeOfRawData; int PointerToRawData; int PointerToRelocations; int PointerToLinenumbers; int NumberOfRelocations; int NumberOfLinenumbers; int Characteristics; } 568 569 public static class IMAGE_RESOURCE_DIRECTORY { 570 int Characteristics; int TimeDateStamp; int MajorVersion; int MinorVersion; int NumberOfNamedEntries; int NumberOfIdEntries; final static int SIZEOF = 16; 577 } 578 579 public static class IMAGE_RESOURCE_DIRECTORY_ENTRY { 580 int NameOffset; boolean NameIsString; int Name; int Id; int OffsetToData; int OffsetToDirectory; boolean DataIsDirectory; } 590 591 public static class IMAGE_RESOURCE_DATA_ENTRY { 592 int OffsetToData; int Size; int CodePage; int Reserved; } 597 598 public static class NEWHEADER { 599 int Reserved; int ResType; int ResCount; } 603 604 public static class ICONRESDIR { 605 int Width; int Height; int ColorCount; int reserved; } 610 611 public static class CURSORDIR { 612 int Width; int Height; } 615 616 public static class RESDIR { 617 ICONRESDIR Icon = new ICONRESDIR(); 619 CURSORDIR Cursor = new CURSORDIR(); 620 int Planes; int BitCount; int BytesInRes; int IconCursorId; } 625 626 public static class BITMAPINFOHEADER { 627 int biSize; int biWidth; int biHeight; int biPlanes; int biBitCount; int biCompression; int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; int biClrUsed; int biClrImportant; } 639 640 static class RGBQUAD { 641 int rgBlue; int rgbGreen; int rgbRed; int rgbReserved; } 646 static class BITMAPINFO { 647 BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); 648 RGBQUAD[] bmiColors = null; 649 } 650 static void read(RandomAccessFile raf, BITMAPINFOHEADER bih) throws IOException { 651 bih.biSize = read4(raf); 652 bih.biWidth = read4(raf); 653 bih.biHeight = read4(raf); 654 bih.biPlanes = readU2(raf); 655 bih.biBitCount = readU2(raf); 656 bih.biCompression = read4(raf); 657 bih.biSizeImage = read4(raf); 658 bih.biXPelsPerMeter = read4(raf); 659 bih.biYPelsPerMeter = read4(raf); 660 bih.biClrUsed = read4(raf); 661 bih.biClrImportant = read4(raf); 662 } 663 static void read(RandomAccessFile raf, BITMAPINFO bi) throws IOException { 664 read(raf, bi.bmiHeader); 665 } 666 667 static int readU2(RandomAccessFile raf) throws IOException { 668 int b0 = raf.readByte() & 0xFF; 669 int b1 = raf.readByte() & 0xFF; 670 return (b1 << 8 | b0); 671 } 672 static int read4(RandomAccessFile raf) throws IOException { 673 int b0 = raf.readByte() & 0xFF; 674 int b1 = raf.readByte() & 0xFF; 675 int b2 = raf.readByte() & 0xFF; 676 int b3 = raf.readByte() & 0xFF; 677 return b3 << 24 | b2 << 16 | b1 << 8 | b0; 678 } 679 static void write4(RandomAccessFile raf, int value) throws IOException { 680 raf.write(value & 0xFF); 681 raf.write((value >> 8) & 0xFF); 682 raf.write((value >> 16) & 0xFF); 683 raf.write((value >> 24) & 0xFF); 684 } 685 static void writeU2(RandomAccessFile raf, int value) throws IOException { 686 raf.write(value & 0xFF); 687 raf.write((value >> 8) & 0xFF); 688 } 689 static void read(RandomAccessFile raf, IMAGE_DOS_HEADER idh) throws IOException { 690 idh.e_magic = readU2(raf); 691 idh.e_cblp = readU2(raf); 692 idh.e_cp = readU2(raf); 693 idh.e_crlc = readU2(raf); 694 idh.e_cparhdr = readU2(raf); 695 idh.e_minalloc = readU2(raf); 696 idh.e_maxalloc = readU2(raf); 697 idh.e_ss = readU2(raf); 698 idh.e_sp = readU2(raf); 699 idh.e_csum = readU2(raf); 700 idh.e_ip = readU2(raf); 701 idh.e_cs = readU2(raf); 702 idh.e_lfarlc = readU2(raf); 703 idh.e_ovno = readU2(raf); 704 for (int i = 0; i < idh.e_res.length; i++) idh.e_res[i] = readU2(raf); 705 idh.e_oemid = readU2(raf); 706 idh.e_oeminfo = readU2(raf); 707 for (int i = 0; i < idh.e_res2.length; i++) idh.e_res2[i] = readU2(raf); 708 idh.e_lfanew = read4(raf); 709 } 710 static void read(RandomAccessFile raf, IMAGE_FILE_HEADER ifh) throws IOException { 711 ifh.Machine = readU2(raf); 712 ifh.NumberOfSections = readU2(raf); 713 ifh.TimeDateStamp = read4(raf); 714 ifh.PointerToSymbolTable = read4(raf); 715 ifh.NumberOfSymbols = read4(raf); 716 ifh.SizeOfOptionalHeader = readU2(raf); 717 ifh.Characteristics = readU2(raf); 718 } 719 static void read(RandomAccessFile raf, IMAGE_DATA_DIRECTORY idd) throws IOException { 720 idd.VirtualAddress = read4(raf); 721 idd.Size = read4(raf); 722 } 723 static void read(RandomAccessFile raf, IMAGE_OPTIONAL_HEADER ioh) throws IOException { 724 ioh.Magic = readU2(raf); 725 ioh.MajorLinkerVersion = raf.read(); 726 ioh.MinorLinkerVersion = raf.read(); 727 ioh.SizeOfCode = read4(raf); 728 ioh.SizeOfInitializedData = read4(raf); 729 ioh.SizeOfUninitializedData = read4(raf); 730 ioh.AddressOfEntryPoint = read4(raf); 731 ioh.BaseOfCode = read4(raf); 732 ioh.BaseOfData = read4(raf); 733 ioh.ImageBase = read4(raf); 734 ioh.SectionAlignment = read4(raf); 735 ioh.FileAlignment = read4(raf); 736 ioh.MajorOperatingSystemVersion = readU2(raf); 737 ioh.MinorOperatingSystemVersion = readU2(raf); 738 ioh.MajorImageVersion = readU2(raf); 739 ioh.MinorImageVersion = readU2(raf); 740 ioh.MajorSubsystemVersion = readU2(raf); 741 ioh.MinorSubsystemVersion = readU2(raf); 742 ioh.Win32VersionValue = read4(raf); 743 ioh.SizeOfImage = read4(raf); 744 ioh.SizeOfHeaders = read4(raf); 745 ioh.CheckSum = read4(raf); 746 ioh.Subsystem = readU2(raf); 747 ioh.DllCharacteristics = readU2(raf); 748 ioh.SizeOfStackReserve = read4(raf); 749 ioh.SizeOfStackCommit = read4(raf); 750 ioh.SizeOfHeapReserve = read4(raf); 751 ioh.SizeOfHeapCommit = read4(raf); 752 ioh.LoaderFlags = read4(raf); 753 ioh.NumberOfRvaAndSizes = read4(raf); 754 for (int i = 0 ; i < ioh.DataDirectory.length; i++) { 755 ioh.DataDirectory[i] = new IMAGE_DATA_DIRECTORY(); 756 read(raf, ioh.DataDirectory[i]); 757 } 758 } 759 static void read(RandomAccessFile raf, IMAGE_NT_HEADERS inh) throws IOException { 760 inh.Signature = read4(raf); 761 read(raf, inh.FileHeader); 762 read(raf, inh.OptionalHeader); 763 } 764 static void read(RandomAccessFile raf, IMAGE_SECTION_HEADER ish) throws IOException { 765 for (int i = 0 ; i < ish.Name.length; i++) ish.Name[i] = raf.read(); 766 ish.Misc_VirtualSize = read4(raf); 767 ish.VirtualAddress = read4(raf); 768 ish.SizeOfRawData = read4(raf); 769 ish.PointerToRawData = read4(raf); 770 ish.PointerToRelocations = read4(raf); 771 ish.PointerToLinenumbers = read4(raf); 772 ish.NumberOfRelocations = readU2(raf); 773 ish.NumberOfLinenumbers = readU2(raf); 774 ish.Characteristics = read4(raf); 775 } 776 static void read(RandomAccessFile raf, IMAGE_RESOURCE_DIRECTORY ird) throws IOException { 777 ird.Characteristics = read4(raf); 778 ird.TimeDateStamp = read4(raf); 779 ird.MajorVersion = readU2(raf); 780 ird.MinorVersion = readU2(raf); 781 ird.NumberOfNamedEntries = readU2(raf); 782 ird.NumberOfIdEntries = readU2(raf); 783 } 784 static void read(RandomAccessFile raf, IMAGE_RESOURCE_DIRECTORY_ENTRY irde) throws IOException { 785 irde.Name = read4(raf); 786 irde.OffsetToData = read4(raf); 787 irde.NameOffset = irde.Name & ~ (1 << 31); 789 irde.NameIsString = (irde.Name & (1 << 31)) != 0; 790 irde.Id = irde.Name & 0xFFFF; 791 irde.OffsetToDirectory = irde.OffsetToData & ~ (1 << 31); 792 irde.DataIsDirectory = (irde.OffsetToData & (1 << 31)) != 0; 793 } 794 static void read(RandomAccessFile raf, IMAGE_RESOURCE_DATA_ENTRY irde) throws IOException { 795 irde.OffsetToData = read4(raf); 796 irde.Size = read4(raf); 797 irde.CodePage = read4(raf); 798 irde.Reserved = read4(raf); 799 } 800 static void read(RandomAccessFile raf, NEWHEADER nh) throws IOException { 801 nh.Reserved = readU2(raf); 802 nh.ResType = readU2(raf); 803 nh.ResCount = readU2(raf); 804 } 805 static void read(RandomAccessFile raf, ICONRESDIR i) throws IOException { 806 i.Width = raf.read(); 807 i.Height = raf.read(); 808 i.ColorCount = raf.read(); 809 i.reserved = raf.read(); 810 } 811 static void read(RandomAccessFile raf, CURSORDIR c) throws IOException { 812 c.Width = readU2(raf); 813 c.Height = readU2(raf); 814 } 815 static void read(RandomAccessFile raf, RESDIR rs) throws IOException { 816 long start = raf.getFilePointer(); 817 read(raf, rs.Icon); 818 raf.seek(start); 819 read(raf, rs.Cursor); 820 rs.Planes = readU2(raf); 821 rs.BitCount = readU2(raf); 822 rs.BytesInRes = read4(raf); 823 rs.IconCursorId = readU2(raf); 824 } 825 826 829 830 static class RGB { 831 832 835 public int red; 836 837 840 public int green; 841 842 845 public int blue; 846 847 static final long serialVersionUID = 3258415023461249074L; 848 849 861 public RGB(int red, int green, int blue) { 862 if ((red > 255) || (red < 0) || 863 (green > 255) || (green < 0) || 864 (blue > 255) || (blue < 0)) 865 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 866 this.red = red; 867 this.green = green; 868 this.blue = blue; 869 } 870 871 881 public boolean equals (Object object) { 882 if (object == this) return true; 883 if (!(object instanceof RGB)) return false; 884 RGB rgb = (RGB)object; 885 return (rgb.red == this.red) && (rgb.green == this.green) && (rgb.blue == this.blue); 886 } 887 888 898 public int hashCode () { 899 return (blue << 16) | (green << 8) | red; 900 } 901 902 908 public String toString () { 909 return "RGB {" + red + ", " + green + ", " + blue + "}"; 911 } 913 914 } 915 static class PaletteData { 916 917 921 public boolean isDirect; 922 923 927 public RGB[] colors; 928 929 932 public int redMask; 933 934 937 public int greenMask; 938 939 942 public int blueMask; 943 944 947 public int redShift; 948 949 952 public int greenShift; 953 954 95
|