Skip to content

Commit

Permalink
Patch jpeg (#158)
Browse files Browse the repository at this point in the history
* Fix error handling in decode jpeg (#155)

* Fix error handling in decode jpeg

* Update internal/decodejpeg/decode.go

Co-authored-by: Joakim Möller <[email protected]>

* Missed a dot

Co-authored-by: Joakim Möller <[email protected]>

* Preemptive bump of raclamdba version

Co-authored-by: Joakim Möller <[email protected]>
  • Loading branch information
Andreas Skyman and joakimmoller authored Nov 30, 2022
1 parent dfe2f71 commit b7c1192
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 37 deletions.
82 changes: 54 additions & 28 deletions internal/decodejpeg/decode.c
Original file line number Diff line number Diff line change
@@ -1,44 +1,70 @@
#include <stdio.h>
#include <setjmp.h>

#include "decode.h"

char jpeg_last_error_message[JMSG_LENGTH_MAX];

void jpeg_error_exit (j_common_ptr cinfo)
{
/* cinfo->err actually points to a jpeg_error_manager struct */
JpegErrorManager* myerr = (JpegErrorManager*) cinfo->err;

/* output_message is a method to print an error message */
( *(cinfo->err->output_message) ) (cinfo);

/* Create the message */
( *(cinfo->err->format_message) ) (cinfo, jpeg_last_error_message);

/* Jump to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}

GLOBAL(struct Image)
read_JPEG_file(char *inbuffer, size_t size)
read_JPEG_file(char* inbuffer, size_t size, char* error)
{
struct Image result;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
struct Image result;
struct jpeg_decompress_struct cinfo;
struct JpegErrorManager jerr;

const int BYTES_PER_SAMPLE = sizeof(JSAMPLE);
JSAMPARRAY buffer; /* Output row buffer */
const int BYTES_PER_SAMPLE = sizeof(JSAMPLE);
JSAMPARRAY buffer; /* Output row buffer */

int row_stride; /* physical row width in output buffer */
int row_stride; /* physical row width in output buffer */

cinfo.err = jpeg_std_error(&jerr);
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = jpeg_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error. */
jpeg_destroy_decompress(&cinfo);
strcpy(error, jpeg_last_error_message);
return result;
}

jpeg_create_decompress(&cinfo);
jpeg_create_decompress(&cinfo);

jpeg_mem_src(&cinfo, inbuffer, size);
jpeg_mem_src(&cinfo, inbuffer, size);

(void)jpeg_read_header(&cinfo, TRUE);
(void)jpeg_read_header(&cinfo, TRUE);

(void)jpeg_start_decompress(&cinfo);
result.pix = (char *)malloc(cinfo.output_height * cinfo.output_width
* cinfo.output_components * BYTES_PER_SAMPLE);
result.width = cinfo.output_width;
result.height = cinfo.output_height;
(void)jpeg_start_decompress(&cinfo);
row_stride = cinfo.output_width * cinfo.output_components * BYTES_PER_SAMPLE;
result.pix = (char *)malloc(cinfo.output_height * row_stride);
result.width = cinfo.output_width;
result.height = cinfo.output_height;

row_stride = cinfo.output_width * cinfo.output_components * BYTES_PER_SAMPLE;
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);

while (cinfo.output_scanline < cinfo.output_height)
{
(void)jpeg_read_scanlines(&cinfo, buffer, 1);
memcpy(&(result.pix)[(cinfo.output_scanline - 1) * row_stride],
buffer[0],
row_stride);
}
(void)jpeg_finish_decompress(&cinfo);
while (cinfo.output_scanline < cinfo.output_height)
{
(void)jpeg_read_scanlines(&cinfo, buffer, 1);
memcpy(&(result.pix)[(cinfo.output_scanline - 1) * row_stride],
buffer[0],
row_stride);
}
(void)jpeg_finish_decompress(&cinfo);

jpeg_destroy_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);

return result;
return result;
}
25 changes: 19 additions & 6 deletions internal/decodejpeg/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,35 @@ import "C"
import (
"bytes"
"encoding/binary"
"fmt"
"strings"
"unsafe"
)

//JpegImageData converts a grayscale image encoded in 12-bit jpeg to raw data
// JpegImageData converts a grayscale image encoded in 12-bit jpeg to raw data
func JpegImageData(jpegData []byte) (rawData []uint16, height int, width int, err error) {

jpegChar := C.CString(string(jpegData))
defer C.free(unsafe.Pointer(jpegChar))

imageData, err := C.read_JPEG_file(jpegChar, C.size_t(len(jpegData)))
if err != nil {
return rawData, height, width, err
}
jErrBuf := strings.Repeat(" ", C.JMSG_LENGTH_MAX)

jpegErr := C.CString(string(jErrBuf))
defer C.free(unsafe.Pointer(jpegErr))

imageData, err := C.read_JPEG_file(jpegChar, C.size_t(len(jpegData)), jpegErr)
defer C.free(unsafe.Pointer(imageData.pix))

pixelString := C.GoStringN(imageData.pix, C.int(imageData.width*imageData.height*C.sizeof_short))
jErr := C.GoStringN(jpegErr, C.JMSG_LENGTH_MAX)
jErr = strings.Trim(jErr, " ")
if jErr != "" {
return rawData, height, width, fmt.Errorf("JPEG decode error: %v", jErr)
}

pixelString := C.GoStringN(
imageData.pix,
C.int(imageData.width*imageData.height*C.sizeof_short),
)
height = int(imageData.height)
width = int(imageData.width)
buffer := bytes.NewBufferString(pixelString)
Expand Down
12 changes: 10 additions & 2 deletions internal/decodejpeg/decode.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include "jpeglib.h"

typedef struct Image
{
char *pix;
char* pix;
JDIMENSION width;
JDIMENSION height;
} Image;

struct Image read_JPEG_file(char *, size_t);
typedef struct JpegErrorManager {
/* "public" fields */
struct jpeg_error_mgr pub;
/* for return to caller */
jmp_buf setjmp_buffer;
} JpegErrorManager;

struct Image read_JPEG_file(char*, size_t, char*);
2 changes: 1 addition & 1 deletion raclambda/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from raclambda.raclambda_stack import RacLambdaStack


RAC_VERSION = "v0.2.6"
RAC_VERSION = "v0.2.8"
RAC_OS = "Linux"
RAC_URL = f"https://github.com/innosat-mats/rac-extract-payload/releases/download/{RAC_VERSION}/Rac_for_{RAC_OS}.tar.gz" # noqa: E501
RAC_DIR = "./raclambda/handler"
Expand Down

0 comments on commit b7c1192

Please sign in to comment.