Skip to content

Commit

Permalink
Fix grayscale encoded PNGs not being decoded correctly, fixes #1181 (…
Browse files Browse the repository at this point in the history
…Thanks rdebath)
  • Loading branch information
UnknownShadow200 committed Apr 30, 2024
1 parent 574e0b5 commit e90e63e
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 25 deletions.
14 changes: 8 additions & 6 deletions src/Bitmap.c
Expand Up @@ -163,8 +163,8 @@ static void Png_Reconstruct(cc_uint8 type, cc_uint8 bytesPerPixel, cc_uint8* lin

/* 7.2 Scanlines */
#define PNG_Do_Grayscale(dstI, src, scale) rgb = (src) * scale; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
#define PNG_Do_Grayscale_8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, 255); dst--; src -= 2;
#define PNG_Do_Grayscale_A__8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, src[1]); dst--; src -= 1;
#define PNG_Do_Grayscale_8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, 255); dst--; src -= 1;
#define PNG_Do_Grayscale_A__8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, src[1]); dst--; src -= 2;
#define PNG_Do_RGB__8() Bitmap_Set(*dst, src[0], src[1], src[2], 255); dst--; src -= 3;
#define PNG_Do_RGB_A__8() Bitmap_Set(*dst, src[0], src[1], src[2], src[3]); dst++; src += 4;
#define PNG_Do_Palette__8() *dst-- = palette[*src--];
Expand Down Expand Up @@ -488,12 +488,14 @@ cc_result Png_Decode(struct Bitmap* bmp, struct Stream* stream) {
/* immediately into the destination colour format */
if (colorspace == PNG_COLOR_RGB_A) {
/* Prior line is no longer needed and can be overwritten now */
rowExpander(bmp->width, palette, &prior[1], Bitmap_GetRow(bmp, rowY - 1));
/* Current line is also no longer needed and can be overwritten now */
if (rowY == bmp->height - 1)
rowExpander(bmp->width, palette, &scanline[1], Bitmap_GetRow(bmp, rowY));
rowExpander(bmp->width, palette, &prior[1], Bitmap_GetRow(bmp, rowY - 1));
}
}

/* Current line is also no longer needed and can be overwritten now */
if (colorspace == PNG_COLOR_RGB_A && rowY == bmp->height - 1) {
rowExpander(bmp->width, palette, &scanline[1], Bitmap_GetRow(bmp, rowY));
}
}

/* Check if image fully decoded or not */
Expand Down
4 changes: 3 additions & 1 deletion src/Http_Worker.c
Expand Up @@ -496,13 +496,15 @@ static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct H
static cc_result HttpConnection_Read(struct HttpConnection* conn, cc_uint8* data, cc_uint32 count, cc_uint32* read) {
if (conn->sslCtx)
return SSL_Read(conn->sslCtx, data, count, read);

return Socket_Read(conn->socket, data, count, read);
}

static cc_result HttpConnection_Write(struct HttpConnection* conn, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote) {
if (conn->sslCtx)
return SSL_Write(conn->sslCtx, data, count, wrote);
return Socket_Write(conn->socket, data, count, wrote);

return Socket_WriteAll(conn->socket, data, count, wrote);
}


Expand Down
2 changes: 2 additions & 0 deletions src/Platform.h
Expand Up @@ -270,6 +270,8 @@ cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* m
cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified);
/* Attempts to close the given socket */
void Socket_Close(cc_socket s);
/* Attempts to write all data to the given socket, returning ERR_END_OF_STREAM if it could not */
cc_result Socket_WriteAll(cc_socket socket, const cc_uint8* data, cc_uint32 count);

#ifdef CC_BUILD_MOBILE
void Platform_ShareScreenshot(const cc_string* filename);
Expand Down
21 changes: 3 additions & 18 deletions src/SSL.c
Expand Up @@ -105,21 +105,6 @@ static SECURITY_STATUS SSL_CreateHandle(struct SSLContext* ctx) {
&cred, NULL, NULL, &ctx->handle, NULL);
}

static cc_result SSL_SendRaw(cc_socket socket, const cc_uint8* data, cc_uint32 count) {
cc_uint32 sent;
cc_result res;

while (count)
{
if ((res = Socket_Write(socket, data, count, &sent))) return res;
if (!sent) return ERR_END_OF_STREAM;

data += sent;
count -= sent;
}
return 0;
}

static cc_result SSL_RecvRaw(struct SSLContext* ctx) {
cc_uint32 read;
cc_result res;
Expand Down Expand Up @@ -160,7 +145,7 @@ static SECURITY_STATUS SSL_Connect(struct SSLContext* ctx, const char* hostname)

/* Send initial handshake to the server (if there is one) */
if (out_buffers[0].pvBuffer) {
res = SSL_SendRaw(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
res = Socket_WriteAll(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
FP_FreeContextBuffer(out_buffers[0].pvBuffer);
}
return res;
Expand Down Expand Up @@ -221,7 +206,7 @@ static SECURITY_STATUS SSL_Negotiate(struct SSLContext* ctx) {

/* Need to send data to the server */
if (sec == SEC_I_CONTINUE_NEEDED) {
res = SSL_SendRaw(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
res = Socket_WriteAll(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
FP_FreeContextBuffer(out_buffers[0].pvBuffer); /* TODO always free? */

if (res) return res;
Expand Down Expand Up @@ -392,7 +377,7 @@ static cc_result SSL_WriteChunk(struct SSLContext* s, const cc_uint8* data, cc_u
/* NOTE: Okay to write in one go, since all three buffers will be contiguous */
/* (as TLS record header size will always be the same size) */
total = buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer;
return SSL_SendRaw(s->socket, buffer, total);
return Socket_WriteAll(s->socket, buffer, total);
}

cc_result SSL_Write(void* ctx, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote) {
Expand Down
16 changes: 16 additions & 0 deletions src/_PlatformBase.h
Expand Up @@ -2,6 +2,7 @@
#include "String.h"
#include "Logger.h"
#include "Constants.h"
#include "Errors.h"
cc_bool Platform_ReadonlyFilesystem;

/*########################################################################################################################*
Expand Down Expand Up @@ -89,6 +90,21 @@ int Stopwatch_ElapsedMS(cc_uint64 beg, cc_uint64 end) {
return (int)raw / 1000;
}

cc_result Socket_WriteAll(cc_socket socket, const cc_uint8* data, cc_uint32 count) {
cc_uint32 sent;
cc_result res;

while (count)
{
if ((res = Socket_Write(socket, data, count, &sent))) return res;
if (!sent) return ERR_END_OF_STREAM;

data += sent;
count -= sent;
}
return 0;
}


/*########################################################################################################################*
*-------------------------------------------------------Dynamic lib-------------------------------------------------------*
Expand Down

0 comments on commit e90e63e

Please sign in to comment.