On Thu, 1 Jul 2004, Martin Schröder wrote:
Thanks. The file is at http://www.ndh.net/home/mauz/majox.de/newsgroup/compile-ablauf.png
The pdf_buf (pdf_buf_size = 16384 bytes) is overrun by the long lines (18051 pixels, R + G + B) in writepng(). There is always the pdfroom() macro called, but why then isn't the overrun detected? The reason is in ptexmac.h, whose pdfroom(n) macro is used (and not the pdf_room(#) macro from pdftex.ch!). Funnily in ptexmac.h these macro lines if (pdfbufsize - n < 0) \ pdftex_fail("PDF output buffer overflowed"); \ do never flag any overflow, but these if (pdfbufsize < n) \ pdftex_fail("PDF output buffer overflowed"); \ work ok, e. g. an overflow error is generated with the given image. Macro weirdness, something with signed/unsigned? So this would be a change to ptexmac.h. Similar subtraction is done also in pdf_room(#) in pdftex.ch, so maybe one should change this also, to be safe. Then for handling such big images one could increase pdf_buf_size to maybe 25000. Instead here is a patch that cuts arbitrary long image lines into snipplets always fitting into pdf_buf_size. Tested with the above image. Regards, Hartmut --- writepng.c.orig Mon Jul 1 18:07:00 2002 +++ writepng.c Thu Jul 1 23:14:33 2004 @@ -67,7 +67,7 @@ void write_png(integer img) { - int i, j; + int i, j, k, l; integer palette_objnum = 0; png_bytep row, *rows; pdf_puts("/Type /XObject\n/Subtype /Image\n"); @@ -100,9 +100,14 @@ row = xtalloc(png_info(img)->rowbytes, png_byte); for (i = 0; i < (int)png_info(img)->height; i++) { png_read_row(png_ptr(img), row, NULL); - pdfroom(png_info(img)->rowbytes); - for (j = 0; j < (int)png_info(img)->rowbytes; j++) - pdfbuf[pdfptr++] = row[j]; + k = png_info(img)->rowbytes; + while(k > 0) { + l = (k > pdfbufsize)? pdfbufsize : k; + pdfroom(l); + for (j = 0; j < l; j++) + pdfbuf[pdfptr++] = row[j]; + k -= l; + } } xfree(row); } @@ -115,9 +120,14 @@ png_read_image(png_ptr(img), rows); for (i = 0; i < (int)png_info(img)->height; i++) { row = rows[i]; - pdfroom(png_info(img)->rowbytes); - for (j = 0; j < (int)png_info(img)->rowbytes; j++) - pdfbuf[pdfptr++] = *row++; + k = png_info(img)->rowbytes; + while(k > 0) { + l = (k > pdfbufsize)? pdfbufsize : k; + pdfroom(l); + for (j = 0; j < l; j++) + pdfbuf[pdfptr++] = *row++; + k -= l; + } xfree(rows[i]); } xfree(rows);