[GH-ISSUE #388] image_buffer error in version 1.1.5 #310

Closed
opened 2026-05-05 12:08:03 -06:00 by gitea-mirror · 12 comments
Owner

Originally created by @slw287r on GitHub (Jan 3, 2023).
Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/388

Originally assigned to: @jmcnamara on GitHub.

I encountered the follow warning and failed to insert cairo picture from memory on CentOS Linux:

[WARNING]: worksheet image insertion: couldn't read image type for: image_buffer.

I switched on and off of USE_MEM_FILE and got the same error.

option(USE_MEM_FILE "Use fmemopen()/open_memstream() in place of temporary files" ON)

It worked on macOS for version 1.1.5 and CentOS Linux for version 1.1.3 (1.1.4 not tested).

My demo scripts (a.c):

#include <xlsxwriter.h>
#include <cairo/cairo.h>

#define WIDTH 1500
#define HEIGHT 300

lxw_image_options img_opt = {
	.x_scale = 0.1 / 1.5,
	.y_scale = 0.1 / 1.5,
	.object_position = LXW_OBJECT_MOVE_AND_SIZE_AFTER,
	.description = ""
};

typedef struct {
	unsigned char *data;
	size_t length;
} png_t;

static cairo_status_t png_write_callback(void *closure, const unsigned char *data,
        unsigned int length)
{
	png_t *png = (png_t *)closure;
	size_t new_length = png->length + length;
	unsigned char *new_data;
	if ((new_data = realloc(png->data, new_length)) == NULL)
		return CAIRO_STATUS_WRITE_ERROR;
	memcpy(&new_data[png->length], data, length);
	png->data = new_data;
	png->length = new_length;
	return CAIRO_STATUS_SUCCESS;
}

int main()
{
	png_t *png = calloc(1, sizeof(png_t));
	cairo_surface_t *sf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
	cairo_t *cr = cairo_create(sf);
	cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
	cairo_set_source_rgb(cr, 0, 0, 0);
	cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size(cr, 200.0);
	cairo_move_to(cr, WIDTH / 10, HEIGHT / 1.25);
	cairo_show_text(cr, "FOOBAR");
	cairo_surface_write_to_png_stream(sf, png_write_callback, png);
	cairo_destroy(cr);
	cairo_surface_destroy(sf);

	lxw_workbook *wb = workbook_new("foo.xlsx");
	lxw_worksheet *ws = workbook_add_worksheet(wb, "bar");
	worksheet_insert_image_buffer_opt(ws, 0, 0, png->data, png->length, &img_opt);
	lxw_error e = workbook_close(wb);
	if (e) {
		fprintf(stderr, "Error closing workbook, %d = %s\n", e, lxw_strerror(e));
		return e;
	}
	free((char *)png->data);
	free(png);
	return 0;
}

Compile and run:

gcc -o a a.c -lcairo -lxlsxwriter
./a # create foo.xlsx

Normal foo.xlsx

Originally created by @slw287r on GitHub (Jan 3, 2023). Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/388 Originally assigned to: @jmcnamara on GitHub. I encountered the follow warning and failed to insert cairo picture from memory on CentOS Linux: ``` [WARNING]: worksheet image insertion: couldn't read image type for: image_buffer. ``` I switched on and off of `USE_MEM_FILE` and got the same error. ``` option(USE_MEM_FILE "Use fmemopen()/open_memstream() in place of temporary files" ON) ``` It worked on macOS for version 1.1.5 and CentOS Linux for version 1.1.3 (1.1.4 not tested). My demo scripts (a.c): ```C #include <xlsxwriter.h> #include <cairo/cairo.h> #define WIDTH 1500 #define HEIGHT 300 lxw_image_options img_opt = { .x_scale = 0.1 / 1.5, .y_scale = 0.1 / 1.5, .object_position = LXW_OBJECT_MOVE_AND_SIZE_AFTER, .description = "" }; typedef struct { unsigned char *data; size_t length; } png_t; static cairo_status_t png_write_callback(void *closure, const unsigned char *data, unsigned int length) { png_t *png = (png_t *)closure; size_t new_length = png->length + length; unsigned char *new_data; if ((new_data = realloc(png->data, new_length)) == NULL) return CAIRO_STATUS_WRITE_ERROR; memcpy(&new_data[png->length], data, length); png->data = new_data; png->length = new_length; return CAIRO_STATUS_SUCCESS; } int main() { png_t *png = calloc(1, sizeof(png_t)); cairo_surface_t *sf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT); cairo_t *cr = cairo_create(sf); cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST); cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 200.0); cairo_move_to(cr, WIDTH / 10, HEIGHT / 1.25); cairo_show_text(cr, "FOOBAR"); cairo_surface_write_to_png_stream(sf, png_write_callback, png); cairo_destroy(cr); cairo_surface_destroy(sf); lxw_workbook *wb = workbook_new("foo.xlsx"); lxw_worksheet *ws = workbook_add_worksheet(wb, "bar"); worksheet_insert_image_buffer_opt(ws, 0, 0, png->data, png->length, &img_opt); lxw_error e = workbook_close(wb); if (e) { fprintf(stderr, "Error closing workbook, %d = %s\n", e, lxw_strerror(e)); return e; } free((char *)png->data); free(png); return 0; } ``` Compile and run: ``` gcc -o a a.c -lcairo -lxlsxwriter ./a # create foo.xlsx ``` [Normal foo.xlsx](https://github.com/jmcnamara/libxlsxwriter/files/10335431/foo.xlsx)
gitea-mirror 2026-05-05 12:08:03 -06:00
Author
Owner

@jmcnamara commented on GitHub (Jan 3, 2023):

What is the issue? The image is in the file you attached and I compiled and confirmed that it works with libxlsxwriter version 1.1.5 on Ubuntu 22.04.

screenshot

<!-- gh-comment-id:1369727320 --> @jmcnamara commented on GitHub (Jan 3, 2023): What is the issue? The image is in the file you attached and I compiled and confirmed that it works with libxlsxwriter version 1.1.5 on Ubuntu 22.04. ![screenshot](https://user-images.githubusercontent.com/94267/210359775-fdf8dad9-499b-40f2-9c2e-29100a81f146.png)
Author
Owner

@slw287r commented on GitHub (Jan 3, 2023):

I uploaded the normal xlsx from version 1.1.3 above. Please find the abnormal xlsx without the intended image generated via version 1.1.5 below.

My OS info:
Linux 3.10.0-693.5.2.el7.x86_64 #1 SMP Fri Oct 20 20:32:50 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

foo_bad.xlsx

<!-- gh-comment-id:1369839030 --> @slw287r commented on GitHub (Jan 3, 2023): I uploaded the normal xlsx from version 1.1.3 above. Please find the abnormal xlsx without the intended image generated via version 1.1.5 below. My OS info: Linux 3.10.0-693.5.2.el7.x86_64 #1 SMP Fri Oct 20 20:32:50 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [foo_bad.xlsx](https://github.com/jmcnamara/libxlsxwriter/files/10337353/foo_bad.xlsx)
Author
Owner

@jmcnamara commented on GitHub (Jan 3, 2023):

Could you add this this debug code to your example and run it on the system/version where is doesn't work as expected.

int main()
{
	png_t *png = calloc(1, sizeof(png_t));
	cairo_surface_t *sf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
	cairo_t *cr = cairo_create(sf);
	cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
	cairo_set_source_rgb(cr, 0, 0, 0);
	cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size(cr, 200.0);
	cairo_move_to(cr, WIDTH / 10, HEIGHT / 1.25);
	cairo_show_text(cr, "FOOBAR");
	cairo_surface_write_to_png_stream(sf, png_write_callback, png);
	cairo_destroy(cr);
	cairo_surface_destroy(sf);

	// Add this to your code.
	printf("Version = %s\n", lxw_version());
	printf("Length  = %zu\n", png->length);
	printf("Data    = %c%c%c\n", png->data[1], png->data[2], png->data[3]);

	lxw_workbook *wb = workbook_new("foo.xlsx");
	lxw_worksheet *ws = workbook_add_worksheet(wb, "bar");
	worksheet_insert_image_buffer_opt(ws, 0, 0, png->data, png->length, &img_opt);
	lxw_error e = workbook_close(wb);
	if (e) {
		fprintf(stderr, "Error closing workbook, %d = %s\n", e, lxw_strerror(e));
		return e;
	}
	free((char *)png->data);
	free(png);
	return 0;
}

You should get ouput like this:

Version = 1.1.5
Length  = 13543
Data    = PNG
<!-- gh-comment-id:1369860257 --> @jmcnamara commented on GitHub (Jan 3, 2023): Could you add this this debug code to your example and run it on the system/version where is doesn't work as expected. ```C int main() { png_t *png = calloc(1, sizeof(png_t)); cairo_surface_t *sf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT); cairo_t *cr = cairo_create(sf); cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST); cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 200.0); cairo_move_to(cr, WIDTH / 10, HEIGHT / 1.25); cairo_show_text(cr, "FOOBAR"); cairo_surface_write_to_png_stream(sf, png_write_callback, png); cairo_destroy(cr); cairo_surface_destroy(sf); // Add this to your code. printf("Version = %s\n", lxw_version()); printf("Length = %zu\n", png->length); printf("Data = %c%c%c\n", png->data[1], png->data[2], png->data[3]); lxw_workbook *wb = workbook_new("foo.xlsx"); lxw_worksheet *ws = workbook_add_worksheet(wb, "bar"); worksheet_insert_image_buffer_opt(ws, 0, 0, png->data, png->length, &img_opt); lxw_error e = workbook_close(wb); if (e) { fprintf(stderr, "Error closing workbook, %d = %s\n", e, lxw_strerror(e)); return e; } free((char *)png->data); free(png); return 0; } ``` You should get ouput like this: ``` Version = 1.1.5 Length = 13543 Data = PNG ```
Author
Owner

@slw287r commented on GitHub (Jan 3, 2023):

Here is what I get:

% ./a
Version = 1.1.5
Length  = 12489
Data    = PNG
[WARNING]: worksheet image insertion: couldn't read image type for: image_buffer.

and for v1.1.3, no warning and normal xlsx:

% ./a
Version = 1.1.3
Length  = 12489
Data    = PNG
<!-- gh-comment-id:1369878884 --> @slw287r commented on GitHub (Jan 3, 2023): Here is what I get: ``` % ./a Version = 1.1.5 Length = 12489 Data = PNG [WARNING]: worksheet image insertion: couldn't read image type for: image_buffer. ``` and for v1.1.3, no warning and normal xlsx: ``` % ./a Version = 1.1.3 Length = 12489 Data = PNG ```
Author
Owner

@jmcnamara commented on GitHub (Jan 3, 2023):

Thanks. In the 1.1.5 example are you using USE_MEM_FILE=ON?

<!-- gh-comment-id:1369907170 --> @jmcnamara commented on GitHub (Jan 3, 2023): Thanks. In the 1.1.5 example are you using `USE_MEM_FILE=ON`?
Author
Owner

@slw287r commented on GitHub (Jan 3, 2023):

  • option(USE_MEM_FILE "Use fmemopen()/open_memstream() in place of temporary files" OFF) - normal xlsx
% ./a_mem_off
Version = 1.1.5
Length  = 12489
Data    = PNG
  • option(USE_MEM_FILE "Use fmemopen()/open_memstream() in place of temporary files" ON) - abnormal xlsx
% ./a_mem_on
Version = 1.1.5
Length  = 12489
Data    = PNG
[WARNING]: worksheet image insertion: couldn't read image type for: image_buffer.
<!-- gh-comment-id:1369915577 --> @slw287r commented on GitHub (Jan 3, 2023): * option(USE_MEM_FILE "Use fmemopen()/open_memstream() in place of temporary files" OFF) - normal xlsx ``` % ./a_mem_off Version = 1.1.5 Length = 12489 Data = PNG ``` * option(USE_MEM_FILE "Use fmemopen()/open_memstream() in place of temporary files" ON) - abnormal xlsx ``` % ./a_mem_on Version = 1.1.5 Length = 12489 Data = PNG [WARNING]: worksheet image insertion: couldn't read image type for: image_buffer. ```
Author
Owner

@jmcnamara commented on GitHub (Jan 3, 2023):

@mohd-akram could you have a look at this issue. I can't reproduce it on the mac or Ubuntu systems that I have but I suspect that the issue may be the rewind() below similar to issues you fixed in the second part of your patchset:

https://github.com/jmcnamara/libxlsxwriter/blob/main/src/worksheet.c#L10396

That [WARNING] occurs when the library can't read any image markers in the data but the "PNG" marker is clearly there so I suspect the stream isn't being rewound.

<!-- gh-comment-id:1369930920 --> @jmcnamara commented on GitHub (Jan 3, 2023): @mohd-akram could you have a look at this issue. I can't reproduce it on the mac or Ubuntu systems that I have but I suspect that the issue may be the `rewind()` below similar to issues you fixed in the second part of your patchset: https://github.com/jmcnamara/libxlsxwriter/blob/main/src/worksheet.c#L10396 That `[WARNING]` occurs when the library can't read any image markers in the data but the "PNG" marker is clearly there so I suspect the stream isn't being rewound.
Author
Owner

@mohd-akram commented on GitHub (Jan 3, 2023):

This is a bit of a strange issue. The image buffer code wasn't really touched since it already used buffers. The CentOS version is quite old and I suspect it might be a glibc issue. Can you print what's the glibc version (ldd --version)? Also, try with version 1.1.3 and the USE_FMEMOPEN option set to on, I suspect it didn't work then either.

<!-- gh-comment-id:1369998572 --> @mohd-akram commented on GitHub (Jan 3, 2023): This is a bit of a strange issue. The image buffer code wasn't really touched since it already used buffers. The CentOS version is quite old and I suspect it might be a glibc issue. Can you print what's the glibc version (`ldd --version`)? Also, try with version 1.1.3 and the `USE_FMEMOPEN` option set to on, I suspect it didn't work then either.
Author
Owner

@mohd-akram commented on GitHub (Jan 3, 2023):

Tried this in a centos:7 podman container (glibc 2.17).

@jmcnamara Seems to be the bug mentioned here under notes. Changing w+b to wb+ removes the warning for me (I haven't tried opening the XLSX file). This will also need to be changed in worksheet_set_background_buffer.

@slw287r Try making that change and see if it works for you.

<!-- gh-comment-id:1370050197 --> @mohd-akram commented on GitHub (Jan 3, 2023): Tried this in a `centos:7` podman container (glibc 2.17). @jmcnamara Seems to be the bug mentioned [here](https://manpages.ubuntu.com/manpages/bionic/man3/fmemopen.3.html) under notes. Changing `w+b` to `wb+` removes the warning for me (I haven't tried opening the XLSX file). This will also need to be changed in `worksheet_set_background_buffer`. @slw287r Try making that change and see if it works for you.
Author
Owner

@jmcnamara commented on GitHub (Jan 3, 2023):

@mohd-akram Thanks. Nice detective work.

<!-- gh-comment-id:1370160070 --> @jmcnamara commented on GitHub (Jan 3, 2023): @mohd-akram Thanks. Nice detective work.
Author
Owner

@slw287r commented on GitHub (Jan 4, 2023):

wb+ works for me

Tried this in a centos:7 podman container (glibc 2.17).

@jmcnamara Seems to be the bug mentioned here under notes. Changing w+b to wb+ removes the warning for me (I haven't tried opening the XLSX file). This will also need to be changed in worksheet_set_background_buffer.

@slw287r Try making that change and see if it works for you.

<!-- gh-comment-id:1370369287 --> @slw287r commented on GitHub (Jan 4, 2023): `wb+` works for me > Tried this in a `centos:7` podman container (glibc 2.17). > > @jmcnamara Seems to be the bug mentioned [here](https://manpages.ubuntu.com/manpages/bionic/man3/fmemopen.3.html) under notes. Changing `w+b` to `wb+` removes the warning for me (I haven't tried opening the XLSX file). This will also need to be changed in `worksheet_set_background_buffer`. > > @slw287r Try making that change and see if it works for you.
Author
Owner

@jmcnamara commented on GitHub (Jan 4, 2023):

@slw287r Thanks for the test/report. Fixed on main.

Closing.

<!-- gh-comment-id:1370384589 --> @jmcnamara commented on GitHub (Jan 4, 2023): @slw287r Thanks for the test/report. Fixed on main. Closing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/libxlsxwriter#310
No description provided.