Skip to content

Commit

Permalink
Fix 1/2/4 bit grayscale pngs being incorrectly decoded
Browse files Browse the repository at this point in the history
  • Loading branch information
UnknownShadow200 committed Nov 16, 2018
1 parent e7738b5 commit 02c114d
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 65 deletions.
16 changes: 8 additions & 8 deletions src/Bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ static void Png_Reconstruct(uint8_t type, uint8_t bytesPerPixel, uint8_t* line,

#define Bitmap_Set(dst, r,g,b,a) dst.B = b; dst.G = g; dst.R = r; dst.A = a;

#define PNG_Do_Grayscale(dstI, srcI, scale) rgb = src[srcI] * scale; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
#define PNG_Do_Grayscale_8(dstI, srcI) rgb = src[srcI]; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
#define PNG_Do_Grayscale_A__8(dstI, srcI) rgb = src[srcI]; Bitmap_Set(dst[dstI], rgb, rgb, rgb, src[srcI + 1]);
#define PNG_Do_Grayscale(dstI, src, scale) rgb = (src) * scale; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
#define PNG_Do_Grayscale_8(dstI, srcI) rgb = src[srcI]; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
#define PNG_Do_Grayscale_A__8(dstI, srcI) rgb = src[srcI]; Bitmap_Set(dst[dstI], rgb, rgb, rgb, src[srcI + 1]);
#define PNG_Do_RGB__8(dstI, srcI) Bitmap_Set(dst[dstI], src[srcI], src[srcI + 1], src[srcI + 2], 255);
#define PNG_Do_RGB_A__8(dstI, srcI) Bitmap_Set(dst[dstI], src[srcI], src[srcI + 1], src[srcI + 2], src[srcI + 3]);

Expand Down Expand Up @@ -326,6 +326,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
ReturnCode res;

/* header variables */
static uint32_t samplesPerPixel[7] = { 1, 0, 3, 1, 2, 0, 4 };
uint8_t col, bitsPerSample, bytesPerPixel;
Png_RowExpander rowExpander;
uint32_t scanlineSize, scanlineBytes;
Expand Down Expand Up @@ -384,7 +385,6 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (tmp[11] != 0) return PNG_ERR_FILTER;
if (tmp[12] != 0) return PNG_ERR_INTERLACED;

static uint32_t samplesPerPixel[7] = { 1, 0, 3, 1, 2, 0, 4 };
bytesPerPixel = ((samplesPerPixel[col] * bitsPerSample) + 7) >> 3;
scanlineSize = ((samplesPerPixel[col] * bitsPerSample * bmp->Width) + 7) >> 3;
scanlineBytes = scanlineSize + 1; /* Add 1 byte for filter byte of each scanline */
Expand Down Expand Up @@ -415,8 +415,8 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res;

/* RGB is 16 bits big endian, ignore least significant 8 bits */
transparentCol.B = tmp[0]; transparentCol.G = tmp[0];
transparentCol.R = tmp[0]; transparentCol.A = 0;
transparentCol.R = tmp[0]; transparentCol.G = tmp[0];
transparentCol.B = tmp[0]; transparentCol.A = 0;
} else if (col == PNG_COL_INDEXED) {
if (dataSize > PNG_PALETTE) return PNG_ERR_TRANS_COUNT;
res = Stream_Read(stream, tmp, dataSize);
Expand All @@ -432,8 +432,8 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res;

/* R,G,B is 16 bits big endian, ignore least significant 8 bits */
transparentCol.B = tmp[4]; transparentCol.G = tmp[2];
transparentCol.R = tmp[0]; transparentCol.A = 0;
transparentCol.R = tmp[0]; transparentCol.G = tmp[2];
transparentCol.B = tmp[4]; transparentCol.A = 0;
} else {
return PNG_ERR_TRANS_INVALID;
}
Expand Down
36 changes: 19 additions & 17 deletions src/Block.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ static uint32_t Block_DefinedCustomBlocks[BLOCK_COUNT >> 5];
static char Block_NamesBuffer[STRING_SIZE * BLOCK_COUNT];
#define Block_NamePtr(i) &Block_NamesBuffer[STRING_SIZE * i]

uint8_t Block_TopTex[BLOCK_CPE_COUNT] = { 0, 1, 0, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 24, 23, 6, 6, 7, 9, 4,
36, 37, 16, 11, 25, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 26, 53, 52, };
static uint8_t Block_TopTex[BLOCK_CPE_COUNT] = { 0, 1, 0, 2, 16, 4, 15,
17, 14, 14, 30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 24, 23, 6, 6, 7, 9,
4, 36, 37, 16, 11, 25, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 26, 53, 52 };

uint8_t Block_SideTex[BLOCK_CPE_COUNT] = { 0, 1, 3, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 20, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 40, 39, 5, 5, 7, 8, 35,
36, 37, 16, 11, 41, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 42, 53, 52, };
static uint8_t Block_SideTex[BLOCK_CPE_COUNT] = { 0, 1, 3, 2, 16, 4, 15,
17, 14, 14, 30, 30, 18, 19, 32, 33, 34, 20, 22, 48, 49, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 40, 39, 5, 5, 7, 8,
35, 36, 37, 16, 11, 41, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 42, 53, 52 };

uint8_t Block_BottomTex[BLOCK_CPE_COUNT] = { 0, 1, 2, 2, 16, 4, 15, 17, 14, 14,
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10, 4,
36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 };
static uint8_t Block_BottomTex[BLOCK_CPE_COUNT] = { 0, 1, 2, 2, 16, 4, 15,
17, 14, 14, 30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10,
4, 36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 };

#ifdef EXTENDED_BLOCKS
void Block_SetUsedCount(int count) {
Expand Down Expand Up @@ -589,11 +589,13 @@ float DefaultSet_FogDensity(BlockID b) {
}

PackedCol DefaultSet_FogColour(BlockID b) {
if (b == BLOCK_WATER || b == BLOCK_STILL_WATER)
return PackedCol_Create3(5, 5, 51);
if (b == BLOCK_LAVA || b == BLOCK_STILL_LAVA)
return PackedCol_Create3(153, 25, 0);
return PackedCol_Create4(0, 0, 0, 0);
PackedCol colWater = PACKEDCOL_CONST( 5, 5, 51, 255);
PackedCol colLava = PACKEDCOL_CONST(153, 25, 0, 255);
PackedCol colZero = PACKEDCOL_CONST( 0, 0, 0, 0);

if (b == BLOCK_WATER || b == BLOCK_STILL_WATER) return colWater;
if (b == BLOCK_LAVA || b == BLOCK_STILL_LAVA) return colLava;
return colZero;
}

CollideType DefaultSet_Collide(BlockID b) {
Expand Down
14 changes: 9 additions & 5 deletions src/Drawer2D.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,17 @@ static void Drawer2D_DrawBitmapText(Bitmap* bmp, struct DrawTextArgs* args, int
}

static Size2D Drawer2D_MeasureBitmapText(struct DrawTextArgs* args) {
int point = args->Font.Size;
int i, point = args->Font.Size;
int offset, xPadding;
Size2D total;
String text;

/* adjust coords to make drawn text match GDI fonts */
int i, offset;
int xPadding = Drawer2D_XPadding(point);
Size2D total = { 0, Drawer2D_AdjHeight(point) };
xPadding = Drawer2D_XPadding(point);
total.Width = 0;
total.Height = Drawer2D_AdjHeight(point);

String text = args->Text;
text = args->Text;
for (i = 0; i < text.length; i++) {
char c = text.buffer[i];
if (c == '&' && Drawer2D_ValidColCodeAt(&text, i + 1)) {
Expand Down
36 changes: 21 additions & 15 deletions src/Menus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1628,16 +1628,20 @@ static void KeyBindingsScreen_OnBindingClick(void* screen, void* widget) {
static int KeyBindingsScreen_MakeWidgets(struct KeyBindingsScreen* s, int y, int arrowsY, int leftLength, const char* title, int btnWidth) {
static String lArrow = String_FromConst("<");
static String rArrow = String_FromConst(">");
String text; char textBuffer[STRING_SIZE];
String titleText;
Widget_LeftClick backClick;
int origin, xOffset;
int i, xDir;

int i, origin = y, xOffset = btnWidth / 2 + 5;
origin = y;
xOffset = btnWidth / 2 + 5;
s->CurI = -1;

char textBuffer[STRING_SIZE];
String text = String_FromArray(textBuffer);
String_InitArray(text, textBuffer);

for (i = 0; i < s->BindsCount; i++) {
if (i == leftLength) y = origin; /* reset y for next column */
int xDir = leftLength == -1 ? 0 : (i < leftLength ? -1 : 1);
xDir = leftLength == -1 ? 0 : (i < leftLength ? -1 : 1);

text.length = 0;
KeyBindingsScreen_GetText(s, i, &text);
Expand All @@ -1647,11 +1651,11 @@ static int KeyBindingsScreen_MakeWidgets(struct KeyBindingsScreen* s, int y, int
y += 50; /* distance between buttons */
}

String titleText = String_FromReadonly(title);
titleText = String_FromReadonly(title);
Menu_Label(s, i, &s->Title, &titleText, &s->TitleFont,
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -180); i++;

Widget_LeftClick backClick = Game_UseClassicOptions ? Menu_SwitchClassicOptions : Menu_SwitchOptions;
backClick = Game_UseClassicOptions ? Menu_SwitchClassicOptions : Menu_SwitchOptions;
Menu_Back(s, i, &s->Back, "Done", &s->TitleFont, backClick); i++;
if (!s->LeftPage && !s->RightPage) return i;

Expand Down Expand Up @@ -2997,11 +3001,14 @@ static void TexIdsOverlay_RenderTerrain(struct TexIdsOverlay* s) {
}

static void TexIdsOverlay_RenderTextOverlay(struct TexIdsOverlay* s) {
int x, y, size = s->TileSize;
VertexP3fT2fC4b vertices[TEXID_OVERLAY_VERTICES_COUNT];
VertexP3fT2fC4b* ptr = vertices;
struct TextAtlas* idAtlas;
int size, count;
int x, y, id;

struct TextAtlas* idAtlas = &s->IdAtlas;
size = s->TileSize;
idAtlas = &s->IdAtlas;
idAtlas->Tex.Y = s->YOffset + (size - idAtlas->Tex.Height);

for (y = 0; y < ATLAS2D_TILES_PER_ROW; y++) {
Expand All @@ -3010,11 +3017,12 @@ static void TexIdsOverlay_RenderTextOverlay(struct TexIdsOverlay* s) {
int id = x + y * ATLAS2D_TILES_PER_ROW;
TextAtlas_AddInt(idAtlas, id + s->BaseTexLoc, &ptr);
}
idAtlas->Tex.Y += size;

idAtlas->Tex.Y += size;
if ((y % 4) != 3) continue;
Gfx_BindTexture(idAtlas->Tex.ID);
int count = (int)(ptr - vertices);

count = (int)(ptr - vertices);
GfxCommon_UpdateDynamicVb_IndexedTris(s->DynamicVb, vertices, count);
ptr = vertices;
}
Expand All @@ -3035,16 +3043,14 @@ static void TexIdsOverlay_Render(void* screen, double delta) {
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B);
Menu_Render(s, delta);

rows = Atlas2D_RowsCount;
origXOffset = s->XOffset;
s->BaseTexLoc = 0;

while (rows > 0) {
for (rows = Atlas2D_RowsCount; rows > 0; rows -= ATLAS2D_TILES_PER_ROW) {
TexIdsOverlay_RenderTerrain(s);
TexIdsOverlay_RenderTextOverlay(s);
rows -= ATLAS2D_TILES_PER_ROW;

s->XOffset += s->TileSize * ATLAS2D_TILES_PER_ROW;
s->XOffset += s->TileSize * ATLAS2D_TILES_PER_ROW;
s->BaseTexLoc += ATLAS2D_TILES_PER_ROW * ATLAS2D_TILES_PER_ROW;
}

Expand Down
20 changes: 9 additions & 11 deletions src/PackedCol.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
#include "PackedCol.h"
#include "ExtMath.h"

PackedCol PackedCol_Create4(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
PackedCol c; c.R = r; c.G = g; c.B = b; c.A = a; return c;
}

PackedCol PackedCol_Create3(uint8_t r, uint8_t g, uint8_t b) {
PackedCol c; c.R = r; c.G = g; c.B = b; c.A = 255; return c;
}

bool PackedCol_Equals(PackedCol a, PackedCol b) {
return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
}
Expand Down Expand Up @@ -54,9 +46,12 @@ void PackedCol_ToHex(String* str, PackedCol value) {
}

bool PackedCol_TryParseHex(const String* str, PackedCol* value) {
PackedCol colZero = PACKEDCOL_CONST(0, 0, 0, 0);
int rH, rL, gH, gL, bH, bL;
char* buffer = str->buffer;
*value = PackedCol_Create4(0, 0, 0, 0);
char* buffer;

buffer = str->buffer;
*value = colZero;

/* accept XXYYZZ or #XXYYZZ forms */
if (str->length < 6) return false;
Expand All @@ -67,6 +62,9 @@ bool PackedCol_TryParseHex(const String* str, PackedCol* value) {
if (!PackedCol_Unhex(buffer[2], &gH) || !PackedCol_Unhex(buffer[3], &gL)) return false;
if (!PackedCol_Unhex(buffer[4], &bH) || !PackedCol_Unhex(buffer[5], &bL)) return false;

*value = PackedCol_Create3((rH << 4) | rL, (gH << 4) | gL, (bH << 4) | bL);
value->R = (uint8_t)((rH << 4) | rL);
value->G = (uint8_t)((gH << 4) | gL);
value->B = (uint8_t)((bH << 4) | bL);
value->A = 255;
return true;
}
5 changes: 1 addition & 4 deletions src/PackedCol.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ typedef union PackedColUnion_ { PackedCol C; uint32_t Raw; } PackedColUnion;
#define PACKEDCOL_CONST(r, g, b, a) { r, g, b, a }
#endif
#define PACKEDCOL_WHITE PACKEDCOL_CONST(255, 255, 255, 255)
#define PackedCol_ARGB(r, g, b, a) (((uint32_t)(r) << 16) | ((uint32_t)(g) << 8) | ((uint32_t)(b)) | ((uint32_t)(a) << 24))

PackedCol PackedCol_Create4(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
PackedCol PackedCol_Create3(uint8_t r, uint8_t g, uint8_t b);
bool PackedCol_Equals(PackedCol a, PackedCol b);

#define PackedCol_ARGB(r, g, b, a) (((uint32_t)(r) << 16) | ((uint32_t)(g) << 8) | ((uint32_t)(b)) | ((uint32_t)(a) << 24))
PackedCol PackedCol_Scale(PackedCol value, float t);
PackedCol PackedCol_Lerp(PackedCol a, PackedCol b, float t);
CC_NOINLINE bool PackedCol_Unhex(char hex, int* value);
Expand Down
9 changes: 4 additions & 5 deletions src/PickedPosRenderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ void PickedPosRenderer_Update(struct PickedPos* selected) {
PickedPos_X(0) PickedPos_X(3) /* XMin, XMax */
PickedPos_Z(0) PickedPos_Z(3) /* ZMin, ZMax */
};

PackedCol col = PACKEDCOL_CONST(0, 0, 0, 102);
VertexP3fC4b* ptr;
int i;
Vector3 delta;
float dist, offset, size;
Vector3 coords[4];
Expand Down Expand Up @@ -107,10 +109,7 @@ void PickedPosRenderer_Update(struct PickedPos* selected) {
Vector3_Add1(&coords[3], &selected->Max, offset);
Vector3_Add1(&coords[2], &coords[3], -size);

PackedCol col = PACKEDCOL_CONST(0, 0, 0, 102);
VertexP3fC4b* ptr = pickedPos_vertices;
int i;

ptr = pickedPos_vertices;
for (i = 0; i < Array_Elems(indices); i += 3, ptr++) {
ptr->X = coords[indices[i + 0]].X;
ptr->Y = coords[indices[i + 1]].Y;
Expand Down

0 comments on commit 02c114d

Please sign in to comment.