Fix grayscale encoded PNGs not being decoded correctly, fixes #1181 (Thanks rdebath)

This commit is contained in:
UnknownShadow200 2024-04-30 17:09:44 +10:00
parent 574e0b578a
commit e90e63e92c
5 changed files with 32 additions and 25 deletions

View File

@ -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--];
@ -489,11 +489,13 @@ cc_result Png_Decode(struct Bitmap* bmp, struct Stream* stream) {
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));
}
}
/* 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 */

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
@ -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;
@ -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;
@ -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) {

View File

@ -2,6 +2,7 @@
#include "String.h"
#include "Logger.h"
#include "Constants.h"
#include "Errors.h"
cc_bool Platform_ReadonlyFilesystem;
/*########################################################################################################################*
@ -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-------------------------------------------------------*