Difference between revisions of "GRP Image Format"
From Staredit Network Wiki
m (1 revision imported: Restoring SC1 backup) |
m (formatting, fix cat typo) |
||
Line 2: | Line 2: | ||
*Word = 2 bytes (Short) | *Word = 2 bytes (Short) | ||
*Long = 4 bytes | *Long = 4 bytes | ||
− | *All values are unsigned. | + | *All values are unsigned.<br/><br/> |
− | + | ||
==GRP File Layout== | ==GRP File Layout== | ||
*GRP Header | *GRP Header | ||
Line 113: | Line 112: | ||
[[Category:StarCraft]] | [[Category:StarCraft]] | ||
− | [[Category: | + | [[Category:Reference]] |
[[Category:Modding]] | [[Category:Modding]] |
Revision as of 23:40, 1 August 2015
- Byte = 8 bits
- Word = 2 bytes (Short)
- Long = 4 bytes
- All values are unsigned.
Contents
GRP File Layout
- GRP Header
- Image Header * number of images
- Line Offsets * number of images * image height
- RLE Line * number of images * image height
GRP Header
Struct Size: 6 bytes
- Word - number of images
- Word - maximum width
- Word - maximum height
- Image Headers - one header for each image
Image Header
Struct Size: 8 bytes
- Byte - difference from maximum width (?)
- Byte - difference from maximum height (?)
- Byte - width (in pixels)
- Byte - height (in pixels)
- Long - offset to Line Offsets: the number of bytes from the beginning of the file to the offset for each line.
Line Offsets
Struct Size: 2 bytes * image height
- Word - offset to a RLE Line in bytes from the location of this Line Offsets.
- Word - another offset...
- Word - another...
- Word - another...
- ...
RLE Line
- Byte - Instruction and length:
- if bit 7 is on, it indicates X number pixels are skipped aka transparency.
- if bit 6 is 1 indicates X number of pixels are "this" color. (RLE compression part)
- else X normal pixels should be copied over.
eh... i got lazy, sorry. :/
Example Code
struct definitions struct grp_image_s { uint8_t x_offset; uint8_t y_offset; uint8_t width; uint8_t height; uint32_t offsets; }; struct grp_header_s { uint16_t num_images; uint16_t max_width; uint16_t max_height; }; struct color_s { uint8_t red; uint8_t green; uint8_t blue; uint8_t alpha; };
read the whole file into sprite_data
uint8_t sprite_data = new uint8_t[file_size_in_bytes];
allocate a color_s for each pixel (for just one image)
grp_header_s* gr_file_header = (grp_header_s*)sprite_data; color_s* pixels = new color_s[grp_file_header->max_width * grp_header->max_height ];
decoding algo
for (k = 0; k < num_images; ++k) { current_image = (grp_image_s*)(sprite_data + 6 + (k * sizeof(grp_image_s))); line_offsets = (uint16_t*)(sprite_data + current_image->offsets); image_width = current_image->width; image_height = current_image->height; memset(pixels, 0, grp_header->size_x * grp_header->size_y * sizeof(color_s)); for (y = 0; y < image_height; ++y) { line_data = (uint8_t*)line_offsets + line_offsets[y]; line_pixels = pixels + (image_width * y); for (data_offset = x = 0; x < image_width;) { if (line_data[data_offset] & 0x80) // transparent {x += line_data[data_offset++] & 0x7f;} else if (line_data[data_offset] & 0x40) // data run { length = x + (line_data[data_offset++] & 0x3f); rle_index = line_data[data_offset++]; while (x < length) {line_pixels[x++] = palette[rle_index];} } else // normal { for (length = x + line_data[data_offset++]; x < length;) {line_pixels[x++] = palette[line_data[data_offset++]];} } } } COPY pixels TO ANOTHER PLACE }