decompress_RLE

Run Settings
LanguageC++
Language Version
Run Command
#include <stdio.h> #include <stdint.h> #include <assert.h> #include <stdlib.h> struct Psd{ int64_t width; int64_t height; }; struct Channel{ uint8_t *pointer; int64_t ID; }; struct Layer{ uint64_t channel_count; Channel channel[4]; // max 4 at them moment int64_t top; int64_t bottom; int64_t left; int64_t right; }; struct Clamp{ int64_t x; int64_t y; int64_t w; int64_t h; }; uint8_t *decompress_RLE( Psd *psd, Layer *layer, uint8_t *file_data) { uint64_t total_height = layer->bottom - layer->top; Clamp clamp = {}; if(layer->left < 0) clamp.x = layer->left; if(layer->top < 0) clamp.y = layer->top; if(layer->right > psd->width) clamp.w = psd->width - layer->left; else clamp.w = layer->right - layer->left; if(layer->bottom > psd->height) clamp.h = psd->height - layer->top; else clamp.h = layer->bottom - layer->top; int64_t data_size = clamp.w * clamp.h * 4; if(data_size < 0) data_size = 0; uint8_t *image_data; if(data_size != 0) { image_data = (uint8_t *)malloc(data_size); } for(size_t CC = 0; CC < layer->channel_count; ++CC) { file_data = layer->channel[CC].pointer; uint16_t compression = (uint16_t)file_data[0] * 256 + (uint16_t)file_data[1]; file_data += 2; double opacity = 1; int64_t pixel_pos_c; if(layer->channel[CC].ID == -1) pixel_pos_c = 3; else if(layer->channel[CC].ID == 0) pixel_pos_c = 0; else if(layer->channel[CC].ID == 1) pixel_pos_c = 1; else if(layer->channel[CC].ID == 2) pixel_pos_c = 2; //else assert(false); if(compression == 1) { uint16_t *line_info = (uint16_t *)malloc(total_height * sizeof(*line_info)); for(size_t LINE = 0; LINE < total_height; ++LINE) { line_info[LINE] = (uint16_t)file_data[0] * 256 + (uint16_t)file_data[1]; file_data += sizeof(*line_info); } int64_t pixel_pos_y = clamp.y; for(size_t LINE = 0; LINE < total_height; ++LINE) { uint8_t *layer_end = file_data + line_info[LINE]; if(pixel_pos_y >= 0) { if(pixel_pos_y < clamp.h + clamp.y) { int64_t pixel_pos_x = clamp.x; while(file_data < layer_end) { int8_t head = *file_data; ++file_data; if(head >= 0) { for(size_t i = 0; i < 1 + head; ++i) { uint8_t pixel = *file_data * opacity; ++file_data; if(pixel_pos_x >= 0 && pixel_pos_x < clamp.x + clamp.w) { image_data[pixel_pos_c + (pixel_pos_x*4) + (pixel_pos_y*(clamp.w+clamp.x)*4)] = pixel; } ++pixel_pos_x; } } else if(head > -128) { uint8_t pixel = *file_data * opacity; ++file_data; for(size_t i = 0; i < 1 - head; ++i) { if(pixel_pos_x >= 0 && pixel_pos_x < clamp.x + clamp.y) { image_data[pixel_pos_c + (pixel_pos_x*4) + (pixel_pos_y*(clamp.w+clamp.x)*4)] = pixel; } ++pixel_pos_x; } } else { ++file_data; } } } else { break; } } else { file_data = layer_end; } ++pixel_pos_y; free(line_info); } } else if(compression == 0) { //todo } } return image_data; }
Editor Settings
Theme
Key bindings
Full width
Lines