From bead450f387a90962ffca89126ad6dbf42214631 Mon Sep 17 00:00:00 2001 From: gitlost Date: Wed, 17 Jan 2024 01:45:45 +0000 Subject: [PATCH] - BMP/EMF/PCX/TIF: fix endianness on big-endian machines (note TIF now always written as little-endian - simplifies testing) - READMEs: add date updated --- ChangeLog | 2 + README.bsd | 1 + README.clang-tidy | 3 +- README.linux | 1 + README.macos | 1 + README.windows | 1 + backend/bmp.c | 32 ++-- backend/emf.c | 320 ++++++++++++++++++------------------ backend/output.h | 38 ++++- backend/pcx.c | 20 +-- backend/tests/README | 2 + backend/tests/test_output.c | 6 +- backend/tif.c | 149 +++++++++-------- docs/README | 2 + frontend/tests/README | 2 + win32/README | 2 + 16 files changed, 317 insertions(+), 265 deletions(-) diff --git a/ChangeLog b/ChangeLog index c044ce07..cffc45b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,8 @@ Bugs also lessens to some degree chances of being victim of OOM killer on Linux) - GUI: printing scale dialog: set maxima on X-dim and resolution to keep scale <= 200 +- BMP/EMF/PCX/TIF: fix endianness on big-endian machines (note TIF now always + written as little-endian - simplifies testing) Version 2.13.0 (2023-12-18) diff --git a/README.bsd b/README.bsd index 2654381f..b0465948 100644 --- a/README.bsd +++ b/README.bsd @@ -1,3 +1,4 @@ +% README.bsd 2024-01-17 % Tested on FreeBSD 14.0-RELEASE (with X11 + GNOME installed), OpenBSD 7.4 (with X11) and NetBSD 9.3 (with X11) 1. Prerequisites for building zint diff --git a/README.clang-tidy b/README.clang-tidy index 23eeee0d..688dbfa8 100644 --- a/README.clang-tidy +++ b/README.clang-tidy @@ -1,4 +1,5 @@ -Current as of latest clang-tidy-18 from Ubuntu 22.04 apt package (2023-12-26) +% README.clang-tidy 2024-01-17 +% Current as of latest clang-tidy-18 from Ubuntu 22.04 apt package Requires cmake in "build" sub-directory with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON (for "build/compile_commands.json") and -DCMAKE_BUILD_TYPE=Debug (so `assert()`s defined), and then make (for Qt generated includes). diff --git a/README.linux b/README.linux index 08e0074b..3ebcad38 100644 --- a/README.linux +++ b/README.linux @@ -1,3 +1,4 @@ +% README.linux 2024-01-17 % Tested on Ubuntu 20.04.4 LTS, Ubuntu 22.04 LTS and Fedora Linux 39 (Workstation Edition) 1. Prerequisites for building zint diff --git a/README.macos b/README.macos index 85a8dfed..cc9364d3 100644 --- a/README.macos +++ b/README.macos @@ -1,3 +1,4 @@ +% README.macos 2014-01-17 % Tested on macOS 12.4 Monterey VirtualBox (thanks to https://github.com/myspaghetti/macos-virtualbox) 1. Prerequisites for building zint and zint-qt diff --git a/README.windows b/README.windows index f481356c..35770952 100644 --- a/README.windows +++ b/README.windows @@ -1 +1,2 @@ +% README.windows 2014-01-17 See "README" in the "win32" sub-directory. diff --git a/backend/bmp.c b/backend/bmp.c index ef4e616d..25ffc6c4 100644 --- a/backend/bmp.c +++ b/backend/bmp.c @@ -1,7 +1,7 @@ /* bmp.c - Handles output to Windows Bitmap file */ /* libzint - the open source barcode library - Copyright (C) 2009-2023 Robin Stuart + Copyright (C) 2009-2024 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -97,23 +97,23 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix return ZINT_ERROR_MEMORY; } - file_header.header_field = 0x4d42; /* "BM" */ - file_header.file_size = (uint32_t) file_size; - file_header.reserved = 0; - file_header.data_offset = (uint32_t) data_offset; + out_le_u16(file_header.header_field, 0x4d42); /* "BM" */ + out_le_u32(file_header.file_size, file_size); + out_le_u32(file_header.reserved, 0); + out_le_u32(file_header.data_offset, data_offset); - info_header.header_size = sizeof(bitmap_info_header_t); - info_header.width = symbol->bitmap_width; - info_header.height = symbol->bitmap_height; - info_header.colour_planes = 1; - info_header.bits_per_pixel = bits_per_pixel; - info_header.compression_method = 0; /* BI_RGB */ - info_header.image_size = 0; + out_le_u32(info_header.header_size, sizeof(bitmap_info_header_t)); + out_le_i32(info_header.width, symbol->bitmap_width); + out_le_i32(info_header.height, symbol->bitmap_height); + out_le_u16(info_header.colour_planes, 1); + out_le_u16(info_header.bits_per_pixel, bits_per_pixel); + out_le_u32(info_header.compression_method, 0); /* BI_RGB */ + out_le_u32(info_header.image_size, 0); resolution = symbol->dpmm ? (int) roundf(stripf(symbol->dpmm * 1000.0f)) : 0; /* pixels per metre */ - info_header.horiz_res = resolution; - info_header.vert_res = resolution; - info_header.colours = colour_count; - info_header.important_colours = colour_count; + out_le_i32(info_header.horiz_res, resolution); + out_le_i32(info_header.vert_res, resolution); + out_le_u32(info_header.colours, colour_count); + out_le_u32(info_header.important_colours, colour_count); /* Open output file in binary mode */ if (!fm_open(fmp, symbol, "wb")) { diff --git a/backend/emf.c b/backend/emf.c index a40b9b18..35415980 100644 --- a/backend/emf.c +++ b/backend/emf.c @@ -200,6 +200,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { emr_exttextoutw_t text[6]; float text_fsizes[6]; int text_haligns[6]; + int text_bumped_lens[6]; emr_header_t emr_header; emr_eof_t emr_eof; @@ -303,74 +304,76 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { } /* Header */ - emr_header.type = 0x00000001; /* EMR_HEADER */ - emr_header.size = 108; /* Including extensions */ - emr_header.emf_header.bounds.left = emr_header.emf_header.bounds.top = 0; - emr_header.emf_header.bounds.right = sideways ? bounds_pxy : bounds_pxx; - emr_header.emf_header.bounds.bottom = sideways ? bounds_pxx : bounds_pxy; - emr_header.emf_header.frame.left = emr_header.emf_header.frame.top = 0; - emr_header.emf_header.frame.right = sideways ? frame_cmmy : frame_cmmx; - emr_header.emf_header.frame.bottom = sideways ? frame_cmmx : frame_cmmy; - emr_header.emf_header.record_signature = 0x464d4520; /* ENHMETA_SIGNATURE */ - emr_header.emf_header.version = 0x00010000; - emr_header.emf_header.handles = (fsize2 != 0.0f ? 5 : 4) + ih_ultra_offset; /* Number of graphics objects */ - emr_header.emf_header.reserved = 0x0000; - emr_header.emf_header.n_description = 0; - emr_header.emf_header.off_description = 0; - emr_header.emf_header.n_pal_entries = 0; - emr_header.emf_header.device.cx = sideways ? device_pxy : device_pxx; - emr_header.emf_header.device.cy = sideways ? device_pxx : device_pxy; - emr_header.emf_header.millimeters.cx = sideways ? mmy : mmx; - emr_header.emf_header.millimeters.cy = sideways ? mmx : mmy; + out_le_u32(emr_header.type, 0x00000001); /* EMR_HEADER */ + out_le_u32(emr_header.size, 108); /* Including extensions */ + out_le_i32(emr_header.emf_header.bounds.left, 0); + out_le_i32(emr_header.emf_header.bounds.top, 0); + out_le_i32(emr_header.emf_header.bounds.right, sideways ? bounds_pxy : bounds_pxx); + out_le_i32(emr_header.emf_header.bounds.bottom, sideways ? bounds_pxx : bounds_pxy); + out_le_i32(emr_header.emf_header.frame.left, 0); + out_le_i32(emr_header.emf_header.frame.top, 0); + out_le_i32(emr_header.emf_header.frame.right, sideways ? frame_cmmy : frame_cmmx); + out_le_i32(emr_header.emf_header.frame.bottom, sideways ? frame_cmmx : frame_cmmy); + out_le_u32(emr_header.emf_header.record_signature, 0x464d4520); /* ENHMETA_SIGNATURE */ + out_le_u32(emr_header.emf_header.version, 0x00010000); + out_le_u16(emr_header.emf_header.handles, (fsize2 != 0.0f ? 5 : 4) + ih_ultra_offset); /* No. of graphics objs */ + out_le_u16(emr_header.emf_header.reserved, 0x0000); + out_le_u32(emr_header.emf_header.n_description, 0); + out_le_u32(emr_header.emf_header.off_description, 0); + out_le_u32(emr_header.emf_header.n_pal_entries, 0); + out_le_u32(emr_header.emf_header.device.cx, sideways ? device_pxy : device_pxx); + out_le_u32(emr_header.emf_header.device.cy, sideways ? device_pxx : device_pxy); + out_le_u32(emr_header.emf_header.millimeters.cx, sideways ? mmy : mmx); + out_le_u32(emr_header.emf_header.millimeters.cy, sideways ? mmx : mmy); /* HeaderExtension1 */ - emr_header.emf_header.cb_pixel_format = 0x0000; /* None set */ - emr_header.emf_header.off_pixel_format = 0x0000; /* None set */ - emr_header.emf_header.b_open_gl = 0x0000; /* OpenGL not present */ + out_le_u32(emr_header.emf_header.cb_pixel_format, 0x0000); /* None set */ + out_le_u32(emr_header.emf_header.off_pixel_format, 0x0000); /* None set */ + out_le_u32(emr_header.emf_header.b_open_gl, 0x0000); /* OpenGL not present */ /* HeaderExtension2 */ - emr_header.emf_header.micrometers.cx = sideways ? microny : micronx; - emr_header.emf_header.micrometers.cy = sideways ? micronx : microny; + out_le_u32(emr_header.emf_header.micrometers.cx, sideways ? microny : micronx); + out_le_u32(emr_header.emf_header.micrometers.cy, sideways ? micronx : microny); bytecount = 108; recordcount = 1; - emr_mapmode.type = 0x00000011; /* EMR_SETMAPMODE */ - emr_mapmode.size = 12; - emr_mapmode.mapmode = 0x01; /* MM_TEXT */ + out_le_u32(emr_mapmode.type, 0x00000011); /* EMR_SETMAPMODE */ + out_le_u32(emr_mapmode.size, 12); + out_le_u32(emr_mapmode.mapmode, 0x01); /* MM_TEXT */ bytecount += 12; recordcount++; if (rotate_angle) { - emr_setworldtransform.type = 0x00000023; /* EMR_SETWORLDTRANSFORM */ - emr_setworldtransform.size = 32; - emr_setworldtransform.m11 = rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f; - emr_setworldtransform.m12 = rotate_angle == 90 ? 1.0f : rotate_angle == 180 ? 0.0f : -1.0f; - emr_setworldtransform.m21 = rotate_angle == 90 ? -1.0f : rotate_angle == 180 ? 0.0f : 1.0f; - emr_setworldtransform.m22 = rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f; - emr_setworldtransform.dx = rotate_angle == 90 ? height : rotate_angle == 180 ? width : 0.0f; - emr_setworldtransform.dy = rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? height : width; + out_le_u32(emr_setworldtransform.type, 0x00000023); /* EMR_SETWORLDTRANSFORM */ + out_le_u32(emr_setworldtransform.size, 32); + out_le_float(emr_setworldtransform.m11, rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f); + out_le_float(emr_setworldtransform.m12, rotate_angle == 90 ? 1.0f : rotate_angle == 180 ? 0.0f : -1.0f); + out_le_float(emr_setworldtransform.m21, rotate_angle == 90 ? -1.0f : rotate_angle == 180 ? 0.0f : 1.0f); + out_le_float(emr_setworldtransform.m22, rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? -1.0f : 0.0f); + out_le_float(emr_setworldtransform.dx, rotate_angle == 90 ? height : rotate_angle == 180 ? width : 0.0f); + out_le_float(emr_setworldtransform.dy, rotate_angle == 90 ? 0.0f : rotate_angle == 180 ? height : width); bytecount += 32; recordcount++; } /* Create Brushes */ - emr_createbrushindirect_bg.type = 0x00000027; /* EMR_CREATEBRUSHINDIRECT */ - emr_createbrushindirect_bg.size = 24; - emr_createbrushindirect_bg.ih_brush = 0; - emr_createbrushindirect_bg.log_brush.brush_style = 0x0000; /* BS_SOLID */ + out_le_u32(emr_createbrushindirect_bg.type, 0x00000027); /* EMR_CREATEBRUSHINDIRECT */ + out_le_u32(emr_createbrushindirect_bg.size, 24); + out_le_u32(emr_createbrushindirect_bg.ih_brush, 0); + out_le_u32(emr_createbrushindirect_bg.log_brush.brush_style, 0x0000); /* BS_SOLID */ emr_createbrushindirect_bg.log_brush.color.red = bgred; emr_createbrushindirect_bg.log_brush.color.green = bggrn; emr_createbrushindirect_bg.log_brush.color.blue = bgblu; emr_createbrushindirect_bg.log_brush.color.reserved = 0; - emr_createbrushindirect_bg.log_brush.brush_hatch = 0x0006; /* HS_SOLIDCLR */ + out_le_u32(emr_createbrushindirect_bg.log_brush.brush_hatch, 0x0006); /* HS_SOLIDCLR */ bytecount += 24; recordcount++; if (symbol->symbology == BARCODE_ULTRA) { static const char ultra_chars[] = "0CBMRYGKW"; for (i = 0; i < 9; i++) { - emr_createbrushindirect_colour[i].type = 0x00000027; /* EMR_CREATEBRUSHINDIRECT */ - emr_createbrushindirect_colour[i].size = 24; - emr_createbrushindirect_colour[i].ih_brush = 1 + i; - emr_createbrushindirect_colour[i].log_brush.brush_style = 0x0000; /* BS_SOLID */ + out_le_u32(emr_createbrushindirect_colour[i].type, 0x00000027); /* EMR_CREATEBRUSHINDIRECT */ + out_le_u32(emr_createbrushindirect_colour[i].size, 24); + out_le_u32(emr_createbrushindirect_colour[i].ih_brush, 1 + i); + out_le_u32(emr_createbrushindirect_colour[i].log_brush.brush_style, 0x0000); /* BS_SOLID */ if (i == 0) { emr_createbrushindirect_colour[i].log_brush.color.red = fgred; emr_createbrushindirect_colour[i].log_brush.color.green = fggrn; @@ -382,53 +385,53 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { &emr_createbrushindirect_colour[i].log_brush.color.blue); } emr_createbrushindirect_colour[i].log_brush.color.reserved = 0; - emr_createbrushindirect_colour[i].log_brush.brush_hatch = 0x0006; /* HS_SOLIDCLR */ + out_le_u32(emr_createbrushindirect_colour[i].log_brush.brush_hatch, 0x0006); /* HS_SOLIDCLR */ } bytecount += colours_used * 24; recordcount += colours_used; } else { - emr_createbrushindirect_fg.type = 0x00000027; /* EMR_CREATEBRUSHINDIRECT */ - emr_createbrushindirect_fg.size = 24; - emr_createbrushindirect_fg.ih_brush = 1; - emr_createbrushindirect_fg.log_brush.brush_style = 0x0000; /* BS_SOLID */ + out_le_u32(emr_createbrushindirect_fg.type, 0x00000027); /* EMR_CREATEBRUSHINDIRECT */ + out_le_u32(emr_createbrushindirect_fg.size, 24); + out_le_u32(emr_createbrushindirect_fg.ih_brush, 1); + out_le_u32(emr_createbrushindirect_fg.log_brush.brush_style, 0x0000); /* BS_SOLID */ emr_createbrushindirect_fg.log_brush.color.red = fgred; emr_createbrushindirect_fg.log_brush.color.green = fggrn; emr_createbrushindirect_fg.log_brush.color.blue = fgblu; emr_createbrushindirect_fg.log_brush.color.reserved = 0; - emr_createbrushindirect_fg.log_brush.brush_hatch = 0x0006; /* HS_SOLIDCLR */ + out_le_u32(emr_createbrushindirect_fg.log_brush.brush_hatch, 0x0006); /* HS_SOLIDCLR */ bytecount += 24; recordcount++; } - emr_selectobject_bgbrush.type = 0x00000025; /* EMR_SELECTOBJECT */ - emr_selectobject_bgbrush.size = 12; + out_le_u32(emr_selectobject_bgbrush.type, 0x00000025); /* EMR_SELECTOBJECT */ + out_le_u32(emr_selectobject_bgbrush.size, 12); emr_selectobject_bgbrush.ih_object = emr_createbrushindirect_bg.ih_brush; bytecount += 12; recordcount++; if (symbol->symbology == BARCODE_ULTRA) { for (i = 0; i < 9; i++) { - emr_selectobject_colour[i].type = 0x00000025; /* EMR_SELECTOBJECT */ - emr_selectobject_colour[i].size = 12; + out_le_u32(emr_selectobject_colour[i].type, 0x00000025); /* EMR_SELECTOBJECT */ + out_le_u32(emr_selectobject_colour[i].size, 12); emr_selectobject_colour[i].ih_object = emr_createbrushindirect_colour[i].ih_brush; } bytecount += colours_used * 12; recordcount += colours_used; } else { - emr_selectobject_fgbrush.type = 0x00000025; /* EMR_SELECTOBJECT */ - emr_selectobject_fgbrush.size = 12; + out_le_u32(emr_selectobject_fgbrush.type, 0x00000025); /* EMR_SELECTOBJECT */ + out_le_u32(emr_selectobject_fgbrush.size, 12); emr_selectobject_fgbrush.ih_object = emr_createbrushindirect_fg.ih_brush; bytecount += 12; recordcount++; } /* Create Pens */ - emr_createpen.type = 0x00000026; /* EMR_CREATEPEN */ - emr_createpen.size = 28; - emr_createpen.ih_pen = 2 + ih_ultra_offset; - emr_createpen.log_pen.pen_style = 0x00000005; /* PS_NULL */ - emr_createpen.log_pen.width.x = 1; - emr_createpen.log_pen.width.y = 0; /* ignored */ + out_le_u32(emr_createpen.type, 0x00000026); /* EMR_CREATEPEN */ + out_le_u32(emr_createpen.size, 28); + out_le_u32(emr_createpen.ih_pen, 2 + ih_ultra_offset); + out_le_u32(emr_createpen.log_pen.pen_style, 0x00000005); /* PS_NULL */ + out_le_i32(emr_createpen.log_pen.width.x, 1); + out_le_i32(emr_createpen.log_pen.width.y, 0); /* ignored */ emr_createpen.log_pen.color_ref.red = 0; emr_createpen.log_pen.color_ref.green = 0; emr_createpen.log_pen.color_ref.blue = 0; @@ -436,20 +439,20 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { bytecount += 28; recordcount++; - emr_selectobject_pen.type = 0x00000025; /* EMR_SELECTOBJECT */ - emr_selectobject_pen.size = 12; + out_le_u32(emr_selectobject_pen.type, 0x00000025); /* EMR_SELECTOBJECT */ + out_le_u32(emr_selectobject_pen.size, 12); emr_selectobject_pen.ih_object = emr_createpen.ih_pen; bytecount += 12; recordcount++; if (draw_background) { /* Make background from a rectangle */ - background.type = 0x0000002b; /* EMR_RECTANGLE */ - background.size = 24; - background.box.top = 0; - background.box.left = 0; - background.box.right = width; - background.box.bottom = height; + out_le_u32(background.type, 0x0000002b); /* EMR_RECTANGLE */ + out_le_u32(background.size, 24); + out_le_i32(background.box.top, 0); + out_le_i32(background.box.left, 0); + out_le_i32(background.box.right, width); + out_le_i32(background.box.bottom, height); bytecount += 24; recordcount++; } @@ -458,12 +461,12 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { rect = symbol->vector->rectangles; this_rectangle = 0; while (rect) { - rectangle[this_rectangle].type = 0x0000002b; /* EMR_RECTANGLE */ - rectangle[this_rectangle].size = 24; - rectangle[this_rectangle].box.top = (int32_t) rect->y; - rectangle[this_rectangle].box.bottom = (int32_t) stripf(rect->y + rect->height); - rectangle[this_rectangle].box.left = (int32_t) rect->x; - rectangle[this_rectangle].box.right = (int32_t) stripf(rect->x + rect->width); + out_le_u32(rectangle[this_rectangle].type, 0x0000002b); /* EMR_RECTANGLE */ + out_le_u32(rectangle[this_rectangle].size, 24); + out_le_i32(rectangle[this_rectangle].box.top, rect->y); + out_le_i32(rectangle[this_rectangle].box.bottom, stripf(rect->y + rect->height)); + out_le_i32(rectangle[this_rectangle].box.left, rect->x); + out_le_i32(rectangle[this_rectangle].box.right, stripf(rect->x + rect->width)); this_rectangle++; bytecount += 24; recordcount++; @@ -481,24 +484,24 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { previous_diameter = circ->diameter + circ->width; radius = emf_mul3dpf(0.5f, previous_diameter); } - circle[this_circle].type = 0x0000002a; /* EMR_ELLIPSE */ - circle[this_circle].size = 24; - circle[this_circle].box.top = (int32_t) stripf(circ->y - radius); - circle[this_circle].box.bottom = (int32_t) stripf(circ->y + radius); - circle[this_circle].box.left = (int32_t) stripf(circ->x - radius); - circle[this_circle].box.right = (int32_t) stripf(circ->x + radius); + out_le_u32(circle[this_circle].type, 0x0000002a); /* EMR_ELLIPSE */ + out_le_u32(circle[this_circle].size, 24); + out_le_i32(circle[this_circle].box.top, stripf(circ->y - radius)); + out_le_i32(circle[this_circle].box.bottom, stripf(circ->y + radius)); + out_le_i32(circle[this_circle].box.left, stripf(circ->x - radius)); + out_le_i32(circle[this_circle].box.right, stripf(circ->x + radius)); this_circle++; bytecount += 24; recordcount++; if (symbol->symbology == BARCODE_MAXICODE) { /* Drawing MaxiCode bullseye using overlayed discs */ float inner_radius = radius - circ->width; - circle[this_circle].type = 0x0000002a; /* EMR_ELLIPSE */ - circle[this_circle].size = 24; - circle[this_circle].box.top = (int32_t) stripf(circ->y - inner_radius); - circle[this_circle].box.bottom = (int32_t) stripf(circ->y + inner_radius); - circle[this_circle].box.left = (int32_t) stripf(circ->x - inner_radius); - circle[this_circle].box.right = (int32_t) stripf(circ->x + inner_radius); + out_le_u32(circle[this_circle].type, 0x0000002a); /* EMR_ELLIPSE */ + out_le_u32(circle[this_circle].size, 24); + out_le_i32(circle[this_circle].box.top, stripf(circ->y - inner_radius)); + out_le_i32(circle[this_circle].box.bottom, stripf(circ->y + inner_radius)); + out_le_i32(circle[this_circle].box.left, stripf(circ->x - inner_radius)); + out_le_i32(circle[this_circle].box.right, stripf(circ->x + inner_radius)); this_circle++; bytecount += 24; recordcount++; @@ -512,9 +515,9 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { hex = symbol->vector->hexagons; this_hexagon = 0; while (hex) { - hexagon[this_hexagon].type = 0x00000003; /* EMR_POLYGON */ - hexagon[this_hexagon].size = 76; - hexagon[this_hexagon].count = 6; + out_le_u32(hexagon[this_hexagon].type, 0x00000003); /* EMR_POLYGON */ + out_le_u32(hexagon[this_hexagon].size, 76); + out_le_u32(hexagon[this_hexagon].count, 6); if (previous_diameter != hex->diameter) { previous_diameter = hex->diameter; @@ -524,18 +527,18 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { } /* Note rotation done via world transform */ - hexagon[this_hexagon].a_points_a.x = (int32_t) hex->x; - hexagon[this_hexagon].a_points_a.y = (int32_t) stripf(hex->y + radius); - hexagon[this_hexagon].a_points_b.x = (int32_t) stripf(hex->x + half_sqrt3_radius); - hexagon[this_hexagon].a_points_b.y = (int32_t) stripf(hex->y + half_radius); - hexagon[this_hexagon].a_points_c.x = (int32_t) stripf(hex->x + half_sqrt3_radius); - hexagon[this_hexagon].a_points_c.y = (int32_t) stripf(hex->y - half_radius); - hexagon[this_hexagon].a_points_d.x = (int32_t) hex->x; - hexagon[this_hexagon].a_points_d.y = (int32_t) stripf(hex->y - radius); - hexagon[this_hexagon].a_points_e.x = (int32_t) stripf(hex->x - half_sqrt3_radius); - hexagon[this_hexagon].a_points_e.y = (int32_t) stripf(hex->y - half_radius); - hexagon[this_hexagon].a_points_f.x = (int32_t) stripf(hex->x - half_sqrt3_radius); - hexagon[this_hexagon].a_points_f.y = (int32_t) stripf(hex->y + half_radius); + out_le_i32(hexagon[this_hexagon].a_points_a.x, hex->x); + out_le_i32(hexagon[this_hexagon].a_points_a.y, stripf(hex->y + radius)); + out_le_i32(hexagon[this_hexagon].a_points_b.x, stripf(hex->x + half_sqrt3_radius)); + out_le_i32(hexagon[this_hexagon].a_points_b.y, stripf(hex->y + half_radius)); + out_le_i32(hexagon[this_hexagon].a_points_c.x, stripf(hex->x + half_sqrt3_radius)); + out_le_i32(hexagon[this_hexagon].a_points_c.y, stripf(hex->y - half_radius)); + out_le_i32(hexagon[this_hexagon].a_points_d.x, hex->x); + out_le_i32(hexagon[this_hexagon].a_points_d.y, stripf(hex->y - radius)); + out_le_i32(hexagon[this_hexagon].a_points_e.x, stripf(hex->x - half_sqrt3_radius)); + out_le_i32(hexagon[this_hexagon].a_points_e.y, stripf(hex->y - half_radius)); + out_le_i32(hexagon[this_hexagon].a_points_f.x, stripf(hex->x - half_sqrt3_radius)); + out_le_i32(hexagon[this_hexagon].a_points_f.y, stripf(hex->y + half_radius)); hexagon[this_hexagon].bounds.top = hexagon[this_hexagon].a_points_d.y; hexagon[this_hexagon].bounds.bottom = hexagon[this_hexagon].a_points_a.y; @@ -551,12 +554,12 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { if (symbol->vector->strings) { bold = (symbol->output_options & BOLD_TEXT) && !is_upcean(symbol->symbology); memset(&emr_extcreatefontindirectw, 0, sizeof(emr_extcreatefontindirectw)); - emr_extcreatefontindirectw.type = 0x00000052; /* EMR_EXTCREATEFONTINDIRECTW */ - emr_extcreatefontindirectw.size = 104; - emr_extcreatefontindirectw.ih_fonts = 3 + ih_ultra_offset; - emr_extcreatefontindirectw.elw.height = (int32_t) fsize; - emr_extcreatefontindirectw.elw.width = 0; /* automatic */ - emr_extcreatefontindirectw.elw.weight = bold ? 700 : 400; + out_le_u32(emr_extcreatefontindirectw.type, 0x00000052); /* EMR_EXTCREATEFONTINDIRECTW */ + out_le_u32(emr_extcreatefontindirectw.size, 104); + out_le_u32(emr_extcreatefontindirectw.ih_fonts, 3 + ih_ultra_offset); + out_le_i32(emr_extcreatefontindirectw.elw.height, fsize); + out_le_i32(emr_extcreatefontindirectw.elw.width, 0); /* automatic */ + out_le_i32(emr_extcreatefontindirectw.elw.weight, bold ? 700 : 400); emr_extcreatefontindirectw.elw.char_set = 0x00; /* ANSI_CHARSET */ emr_extcreatefontindirectw.elw.out_precision = 0x00; /* OUT_DEFAULT_PRECIS */ emr_extcreatefontindirectw.elw.clip_precision = 0x00; /* CLIP_DEFAULT_PRECIS */ @@ -565,21 +568,21 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { bytecount += 104; recordcount++; - emr_selectobject_font.type = 0x00000025; /* EMR_SELECTOBJECT */ - emr_selectobject_font.size = 12; + out_le_u32(emr_selectobject_font.type, 0x00000025); /* EMR_SELECTOBJECT */ + out_le_u32(emr_selectobject_font.size, 12); emr_selectobject_font.ih_object = emr_extcreatefontindirectw.ih_fonts; bytecount += 12; recordcount++; if (fsize2) { memcpy(&emr_extcreatefontindirectw2, &emr_extcreatefontindirectw, sizeof(emr_extcreatefontindirectw)); - emr_extcreatefontindirectw2.ih_fonts = 4 + ih_ultra_offset; - emr_extcreatefontindirectw2.elw.height = (int32_t) fsize2; + out_le_u32(emr_extcreatefontindirectw2.ih_fonts, 4 + ih_ultra_offset); + out_le_i32(emr_extcreatefontindirectw2.elw.height, fsize2); bytecount += 104; recordcount++; - emr_selectobject_font2.type = 0x00000025; /* EMR_SELECTOBJECT */ - emr_selectobject_font2.size = 12; + out_le_u32(emr_selectobject_font2.type, 0x00000025); /* EMR_SELECTOBJECT */ + out_le_u32(emr_selectobject_font2.size, 12); emr_selectobject_font2.ih_object = emr_extcreatefontindirectw2.ih_fonts; bytecount += 12; recordcount++; @@ -587,22 +590,22 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { /* Note select aligns counted below in strings loop */ - emr_settextalign_centre.type = 0x00000016; /* EMR_SETTEXTALIGN */ - emr_settextalign_centre.size = 12; - emr_settextalign_centre.text_alignment_mode = 0x0006 | 0x0018; /* TA_CENTER | TA_BASELINE */ + out_le_u32(emr_settextalign_centre.type, 0x00000016); /* EMR_SETTEXTALIGN */ + out_le_u32(emr_settextalign_centre.size, 12); + out_le_u32(emr_settextalign_centre.text_alignment_mode, 0x0006 | 0x0018); /* TA_CENTER | TA_BASELINE */ if (halign_left) { - emr_settextalign_left.type = 0x00000016; /* EMR_SETTEXTALIGN */ - emr_settextalign_left.size = 12; - emr_settextalign_left.text_alignment_mode = 0x0000 | 0x0018; /* TA_LEFT | TA_BASELINE */ + out_le_u32(emr_settextalign_left.type, 0x00000016); /* EMR_SETTEXTALIGN */ + out_le_u32(emr_settextalign_left.size, 12); + out_le_u32(emr_settextalign_left.text_alignment_mode, 0x0000 | 0x0018); /* TA_LEFT | TA_BASELINE */ } if (halign_right) { - emr_settextalign_right.type = 0x00000016; /* EMR_SETTEXTALIGN */ - emr_settextalign_right.size = 12; - emr_settextalign_right.text_alignment_mode = 0x0002 | 0x0018; /* TA_RIGHT | TA_BASELINE */ + out_le_u32(emr_settextalign_right.type, 0x00000016); /* EMR_SETTEXTALIGN */ + out_le_u32(emr_settextalign_right.size, 12); + out_le_u32(emr_settextalign_right.text_alignment_mode, 0x0002 | 0x0018); /* TA_RIGHT | TA_BASELINE */ } - emr_settextcolor.type = 0x0000018; /* EMR_SETTEXTCOLOR */ - emr_settextcolor.size = 12; + out_le_u32(emr_settextcolor.type, 0x0000018); /* EMR_SETTEXTCOLOR */ + out_le_u32(emr_settextcolor.size, 12); emr_settextcolor.color.red = fgred; emr_settextcolor.color.green = fggrn; emr_settextcolor.color.blue = fgblu; @@ -619,7 +622,6 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { current_halign = -1; while (string) { int utfle_len; - int bumped_len; if (string->fsize != current_fsize) { string = string->next; continue; @@ -633,45 +635,45 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { } assert(string->length > 0); utfle_len = emf_utfle_length(string->text, string->length); - bumped_len = emf_bump_up(utfle_len); - if (!(this_string[this_text] = (unsigned char *) malloc(bumped_len))) { + text_bumped_lens[this_text] = emf_bump_up(utfle_len); + if (!(this_string[this_text] = (unsigned char *) malloc(text_bumped_lens[this_text]))) { for (i = 0; i < this_text; i++) { free(this_string[i]); } strcpy(symbol->errtxt, "641: Insufficient memory for EMF string buffer"); return ZINT_ERROR_MEMORY; } - memset(this_string[this_text], 0, bumped_len); - text[this_text].type = 0x00000054; /* EMR_EXTTEXTOUTW */ - text[this_text].size = 76 + bumped_len; - text[this_text].bounds.top = 0; /* ignored */ - text[this_text].bounds.left = 0; /* ignored */ - text[this_text].bounds.right = 0xffffffff; /* ignored */ - text[this_text].bounds.bottom = 0xffffffff; /* ignored */ - text[this_text].i_graphics_mode = 0x00000002; /* GM_ADVANCED */ - text[this_text].ex_scale = 1.0f; - text[this_text].ey_scale = 1.0f; + memset(this_string[this_text], 0, text_bumped_lens[this_text]); + out_le_u32(text[this_text].type, 0x00000054); /* EMR_EXTTEXTOUTW */ + out_le_u32(text[this_text].size, 76 + text_bumped_lens[this_text]); + out_le_i32(text[this_text].bounds.top, 0); /* ignored */ + out_le_i32(text[this_text].bounds.left, 0); /* ignored */ + out_le_i32(text[this_text].bounds.right, 0xffffffff); /* ignored */ + out_le_i32(text[this_text].bounds.bottom, 0xffffffff); /* ignored */ + out_le_u32(text[this_text].i_graphics_mode, 0x00000002); /* GM_ADVANCED */ + out_le_float(text[this_text].ex_scale, 1.0f); + out_le_float(text[this_text].ey_scale, 1.0f); /* Unhack the guard whitespace `gws_left_fudge`/`gws_right_fudge` hack */ if (upcean && string->halign == 1 && string->text[0] == '<') { const float gws_left_fudge = symbol->scale < 0.1f ? 0.1f : symbol->scale; /* 0.5 * 2 * scale */ - text[this_text].w_emr_text.reference.x = (int32_t) (string->x + gws_left_fudge); + out_le_i32(text[this_text].w_emr_text.reference.x, string->x + gws_left_fudge); } else if (upcean && string->halign == 2 && string->text[0] == '>') { const float gws_right_fudge = symbol->scale < 0.1f ? 0.1f : symbol->scale; /* 0.5 * 2 * scale */ - text[this_text].w_emr_text.reference.x = (int32_t) (string->x - gws_right_fudge); + out_le_i32(text[this_text].w_emr_text.reference.x, string->x - gws_right_fudge); } else { - text[this_text].w_emr_text.reference.x = (int32_t) string->x; + out_le_i32(text[this_text].w_emr_text.reference.x, string->x); } - text[this_text].w_emr_text.reference.y = (int32_t) string->y; - text[this_text].w_emr_text.chars = utfle_len; - text[this_text].w_emr_text.off_string = 76; - text[this_text].w_emr_text.options = 0; - text[this_text].w_emr_text.rectangle.top = 0; - text[this_text].w_emr_text.rectangle.left = 0; - text[this_text].w_emr_text.rectangle.right = 0xffffffff; - text[this_text].w_emr_text.rectangle.bottom = 0xffffffff; - text[this_text].w_emr_text.off_dx = 0; + out_le_i32(text[this_text].w_emr_text.reference.y, string->y); + out_le_u32(text[this_text].w_emr_text.chars, utfle_len); + out_le_u32(text[this_text].w_emr_text.off_string, 76); + out_le_u32(text[this_text].w_emr_text.options, 0); + out_le_i32(text[this_text].w_emr_text.rectangle.top, 0); + out_le_i32(text[this_text].w_emr_text.rectangle.left, 0); + out_le_i32(text[this_text].w_emr_text.rectangle.right, 0xffffffff); + out_le_i32(text[this_text].w_emr_text.rectangle.bottom, 0xffffffff); + out_le_u32(text[this_text].w_emr_text.off_dx, 0); emf_utfle_copy(this_string[this_text], string->text, string->length); - bytecount += 76 + bumped_len; + bytecount += 76 + text_bumped_lens[this_text]; recordcount++; this_text++; @@ -682,10 +684,10 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { assert(this_text == string_count); /* Create EOF record */ - emr_eof.type = 0x0000000e; /* EMR_EOF */ - emr_eof.size = 20; /* Assuming no palette entries */ - emr_eof.n_pal_entries = 0; - emr_eof.off_pal_entries = 0; + out_le_u32(emr_eof.type, 0x0000000e); /* EMR_EOF */ + out_le_u32(emr_eof.size, 20); /* Assuming no palette entries */ + out_le_u32(emr_eof.n_pal_entries, 0); + out_le_u32(emr_eof.off_pal_entries, 0); emr_eof.size_last = emr_eof.size; bytecount += 20; recordcount++; @@ -696,8 +698,8 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { } /* Put final counts in header */ - emr_header.emf_header.bytes = bytecount; - emr_header.emf_header.records = recordcount; + out_le_u32(emr_header.emf_header.bytes, bytecount); + out_le_u32(emr_header.emf_header.records, recordcount); /* Send EMF data to file */ if (!fm_open(fmp, symbol, "wb")) { @@ -813,7 +815,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { } } fm_write(&text[i], sizeof(emr_exttextoutw_t), 1, fmp); - fm_write(this_string[i], emf_bump_up(text[i].w_emr_text.chars), 1, fmp); + fm_write(this_string[i], text_bumped_lens[i], 1, fmp); free(this_string[i]); } diff --git a/backend/output.h b/backend/output.h index 6be9e158..7bdb3f27 100644 --- a/backend/output.h +++ b/backend/output.h @@ -1,7 +1,7 @@ /* output.h - Common routines for raster/vector */ /* libzint - the open source barcode library - Copyright (C) 2020-2023 Robin Stuart + Copyright (C) 2020-2024 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -77,6 +77,42 @@ INTERNAL FILE *out_fopen(const char filename[256], const char *mode); INTERNAL FILE *out_win_fopen(const char *filename, const char *mode); #endif +/* Little-endian output */ +#define out_le_u16(b, n) do { \ + unsigned char *bp = (unsigned char *) &(b); \ + uint16_t u16 = (uint16_t) (n); \ + bp[0] = (unsigned char) (u16 & 0xFF); \ + bp[1] = (unsigned char) ((u16 >> 8) & 0xFF); \ + } while (0) + +#define out_le_u32(b, n) do { \ + unsigned char *bp = (unsigned char *) &(b); \ + uint32_t u32 = (uint32_t) (n); \ + bp[0] = (unsigned char) (u32 & 0xFF); \ + bp[1] = (unsigned char) ((u32 >> 8) & 0xFF); \ + bp[2] = (unsigned char) ((u32 >> 16) & 0xFF); \ + bp[3] = (unsigned char) ((u32 >> 24) & 0xFF); \ + } while (0) + +#define out_le_i32(b, n) do { \ + unsigned char *bp = (unsigned char *) &(b); \ + int32_t i32 = (int32_t) (n); \ + bp[0] = (unsigned char) (i32 & 0xFF); \ + bp[1] = (unsigned char) ((i32 >> 8) & 0xFF); \ + bp[2] = (unsigned char) ((i32 >> 16) & 0xFF); \ + bp[3] = (unsigned char) ((i32 >> 24) & 0xFF); \ + } while (0) + +#define out_le_float(b, n) do { \ + unsigned char *bp = (unsigned char *) &(b); \ + float f = n; \ + uint32_t *p_u32 = (uint32_t *) &(f); \ + bp[0] = (unsigned char) (*p_u32 & 0xFF); \ + bp[1] = (unsigned char) ((*p_u32 >> 8) & 0xFF); \ + bp[2] = (unsigned char) ((*p_u32 >> 16) & 0xFF); \ + bp[3] = (unsigned char) ((*p_u32 >> 24) & 0xFF); \ + } while (0) + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/backend/pcx.c b/backend/pcx.c index 099deaba..24ed2462 100644 --- a/backend/pcx.c +++ b/backend/pcx.c @@ -1,7 +1,7 @@ /* pcx.c - Handles output to ZSoft PCX file */ /* libzint - the open source barcode library - Copyright (C) 2009-2023 Robin Stuart + Copyright (C) 2009-2024 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -60,11 +60,11 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix header.version = 5; /* Version 3.0 */ header.encoding = 1; /* Run length encoding */ header.bits_per_pixel = 8; /* TODO: 1-bit monochrome black/white */ - header.window_xmin = 0; - header.window_ymin = 0; - header.window_xmax = symbol->bitmap_width - 1; - header.window_ymax = symbol->bitmap_height - 1; - header.horiz_dpi = symbol->dpmm ? (uint16_t) roundf(stripf(symbol->dpmm * 25.4f)) : 300; + out_le_u16(header.window_xmin, 0); + out_le_u16(header.window_ymin, 0); + out_le_u16(header.window_xmax, symbol->bitmap_width - 1); + out_le_u16(header.window_ymax, symbol->bitmap_height - 1); + out_le_u16(header.horiz_dpi, symbol->dpmm ? roundf(stripf(symbol->dpmm * 25.4f)) : 300); header.vert_dpi = header.horiz_dpi; for (i = 0; i < 48; i++) { @@ -74,11 +74,11 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix header.reserved = 0; header.number_of_planes = 3 + (fgalpha != 0xFF || bgalpha != 0xFF); /* TODO: 1-bit monochrome black/white */ - header.bytes_per_line = bytes_per_line; + out_le_u16(header.bytes_per_line, bytes_per_line); - header.palette_info = 1; /* Colour */ - header.horiz_screen_size = 0; - header.vert_screen_size = 0; + out_le_u16(header.palette_info, 1); /* Colour */ + out_le_u16(header.horiz_screen_size, 0); + out_le_u16(header.vert_screen_size, 0); for (i = 0; i < 54; i++) { header.filler[i] = 0x00; diff --git a/backend/tests/README b/backend/tests/README index 0d9bd54d..62d527f9 100644 --- a/backend/tests/README +++ b/backend/tests/README @@ -1,3 +1,5 @@ +% backend/tests/README 2024-01-17 + Zint backend test suite ----------------------- diff --git a/backend/tests/test_output.c b/backend/tests/test_output.c index 8e1718ce..8cce8264 100644 --- a/backend/tests/test_output.c +++ b/backend/tests/test_output.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2021-2023 Robin Stuart + Copyright (C) 2021-2024 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -123,8 +123,8 @@ static void test_colour_get_rgb(const testCtx *const p_ctx) { unsigned char red = 0, green = 0, blue = 0, alpha = 0, rgb_alpha = 0; int cyan, magenta, yellow, black; int have_alpha; - char rgb[16]; - char cmyk[16]; + char rgb[64]; + char cmyk[64]; if (testContinue(p_ctx, i)) continue; diff --git a/backend/tif.c b/backend/tif.c index 635a7d66..3a61ee74 100644 --- a/backend/tif.c +++ b/backend/tif.c @@ -1,7 +1,7 @@ /* tif.c - Aldus Tagged Image File Format support */ /* libzint - the open source barcode library - Copyright (C) 2016-2023 Robin Stuart + Copyright (C) 2016-2024 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -69,10 +69,6 @@ static void to_cmyk(const char *colour, unsigned char *cmyk) { cmyk[4] = alpha; } -static int is_big_endian(void) { - return (*((const uint16_t *)"\x11\x22") == 0x1122); -} - /* TIFF Revision 6.0 https://www.adobe.io/content/dam/udp/en/open/standards/tiff/TIFF6.pdf */ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pixelbuf) { unsigned char fg[4], bg[4]; @@ -113,6 +109,7 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix int offsets = 0; int ifd_size; uint32_t temp32; + uint16_t temp16; (void) out_colour_get_rgb(symbol->fgcolour, &fg[0], &fg[1], &fg[2], &fg[3]); (void) out_colour_get_rgb(symbol->bgcolour, &bg[0], &bg[1], &bg[2], &bg[3]); @@ -323,13 +320,9 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } /* Header */ - if (is_big_endian()) { - header.byte_order = 0x4D4D; /* "MM" big-endian */ - } else { - header.byte_order = 0x4949; /* "II" little-endian */ - } - header.identity = 42; - header.offset = (uint32_t) free_memory; + out_le_u16(header.byte_order, 0x4949); /* "II" little-endian */ + out_le_u16(header.identity, 42); + out_le_u32(header.offset, free_memory); fm_write(&header, sizeof(tiff_header_t), 1, fmp); total_bytes_put = sizeof(tiff_header_t); @@ -422,29 +415,30 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix (void) fm_close(fmp, symbol); return ZINT_ERROR_MEMORY; } + out_le_u32(temp32, temp32); fm_write(&temp32, 4, 1, fmp); fm_seek(fmp, file_pos, SEEK_SET); } /* Image File Directory */ - tags[entries].tag = 0x0100; /* ImageWidth */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = 1; - tags[entries++].offset = symbol->bitmap_width; + out_le_u16(tags[entries].tag, 0x0100); /* ImageWidth */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, 1); + out_le_u32(tags[entries++].offset, symbol->bitmap_width); - tags[entries].tag = 0x0101; /* ImageLength - number of rows */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = 1; - tags[entries++].offset = symbol->bitmap_height; + out_le_u16(tags[entries].tag, 0x0101); /* ImageLength - number of rows */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, 1); + out_le_u32(tags[entries++].offset, symbol->bitmap_height); if (samples_per_pixel != 1 || bits_per_sample != 1) { - tags[entries].tag = 0x0102; /* BitsPerSample */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = samples_per_pixel; + out_le_u16(tags[entries].tag, 0x0102); /* BitsPerSample */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, samples_per_pixel); if (samples_per_pixel == 1) { - tags[entries++].offset = bits_per_sample; + out_le_u32(tags[entries++].offset, bits_per_sample); } else if (samples_per_pixel == 2) { /* 2 SHORTS fit into LONG offset so packed into offset */ - tags[entries++].offset = (bits_per_sample << 16) | bits_per_sample; + out_le_u32(tags[entries++].offset, (bits_per_sample << 16) | bits_per_sample); } else { update_offsets[offsets++] = entries; tags[entries++].offset = (uint32_t) free_memory; @@ -452,21 +446,21 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } } - tags[entries].tag = 0x0103; /* Compression */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = 1; - tags[entries++].offset = compression; + out_le_u16(tags[entries].tag, 0x0103); /* Compression */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, 1); + out_le_u32(tags[entries++].offset, compression); - tags[entries].tag = 0x0106; /* PhotometricInterpretation */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = 1; - tags[entries++].offset = pmi; + out_le_u16(tags[entries].tag, 0x0106); /* PhotometricInterpretation */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, 1); + out_le_u32(tags[entries++].offset, pmi); - tags[entries].tag = 0x0111; /* StripOffsets */ - tags[entries].type = 4; /* LONG */ - tags[entries].count = strip_count; + out_le_u16(tags[entries].tag, 0x0111); /* StripOffsets */ + out_le_u16(tags[entries].type, 4); /* LONG */ + out_le_u32(tags[entries].count, strip_count); if (strip_count == 1) { - tags[entries++].offset = strip_offset[0]; + out_le_u32(tags[entries++].offset, strip_offset[0]); } else { update_offsets[offsets++] = entries; tags[entries++].offset = (uint32_t) free_memory; @@ -474,78 +468,81 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix } if (samples_per_pixel > 1) { - tags[entries].tag = 0x0115; /* SamplesPerPixel */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = 1; - tags[entries++].offset = samples_per_pixel; + out_le_u16(tags[entries].tag, 0x0115); /* SamplesPerPixel */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, 1); + out_le_u32(tags[entries++].offset, samples_per_pixel); } - tags[entries].tag = 0x0116; /* RowsPerStrip */ - tags[entries].type = 4; /* LONG */ - tags[entries].count = 1; - tags[entries++].offset = rows_per_strip; + out_le_u16(tags[entries].tag, 0x0116); /* RowsPerStrip */ + out_le_u16(tags[entries].type, 4); /* LONG */ + out_le_u32(tags[entries].count, 1); + out_le_u32(tags[entries++].offset, rows_per_strip); - tags[entries].tag = 0x0117; /* StripByteCounts */ - tags[entries].type = 4; /* LONG */ - tags[entries].count = strip_count; + out_le_u16(tags[entries].tag, 0x0117); /* StripByteCounts */ + out_le_u16(tags[entries].type, 4); /* LONG */ + out_le_u32(tags[entries].count, strip_count); if (strip_count == 1) { - tags[entries++].offset = strip_bytes[0]; + out_le_u32(tags[entries++].offset, strip_bytes[0]); } else { update_offsets[offsets++] = entries; tags[entries++].offset = (uint32_t) free_memory; free_memory += strip_count * 4; } - tags[entries].tag = 0x011a; /* XResolution */ - tags[entries].type = 5; /* RATIONAL */ - tags[entries].count = 1; + out_le_u16(tags[entries].tag, 0x011a); /* XResolution */ + out_le_u16(tags[entries].type, 5); /* RATIONAL */ + out_le_u32(tags[entries].count, 1); update_offsets[offsets++] = entries; tags[entries++].offset = (uint32_t) free_memory; free_memory += 8; - tags[entries].tag = 0x011b; /* YResolution */ - tags[entries].type = 5; /* RATIONAL */ - tags[entries].count = 1; + out_le_u16(tags[entries].tag, 0x011b); /* YResolution */ + out_le_u16(tags[entries].type, 5); /* RATIONAL */ + out_le_u32(tags[entries].count, 1); update_offsets[offsets++] = entries; tags[entries++].offset = (uint32_t) free_memory; free_memory += 8; - tags[entries].tag = 0x0128; /* ResolutionUnit */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = 1; + out_le_u16(tags[entries].tag, 0x0128); /* ResolutionUnit */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, 1); if (symbol->dpmm) { - tags[entries++].offset = 3; /* Centimetres */ + out_le_u32(tags[entries++].offset, 3); /* Centimetres */ } else { - tags[entries++].offset = 2; /* Inches */ + out_le_u32(tags[entries++].offset, 2); /* Inches */ } if (color_map_size) { - tags[entries].tag = 0x0140; /* ColorMap */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = color_map_size * 3; + out_le_u16(tags[entries].tag, 0x0140); /* ColorMap */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, color_map_size * 3); update_offsets[offsets++] = entries; tags[entries++].offset = (uint32_t) free_memory; /* free_memory += color_map_size * 3 * 2; Unnecessary as long as last use */ } if (extra_samples) { - tags[entries].tag = 0x0152; /* ExtraSamples */ - tags[entries].type = 3; /* SHORT */ - tags[entries].count = 1; - tags[entries++].offset = extra_samples; + out_le_u16(tags[entries].tag, 0x0152); /* ExtraSamples */ + out_le_u16(tags[entries].type, 3); /* SHORT */ + out_le_u32(tags[entries].count, 1); + out_le_u32(tags[entries++].offset, extra_samples); } ifd_size = sizeof(entries) + sizeof(tiff_tag_t) * entries + sizeof(offset); for (i = 0; i < offsets; i++) { - tags[update_offsets[i]].offset += ifd_size; + out_le_u32(tags[update_offsets[i]].offset, tags[update_offsets[i]].offset + ifd_size); } - fm_write(&entries, sizeof(entries), 1, fmp); + out_le_u16(temp16, entries); + fm_write(&temp16, sizeof(entries), 1, fmp); fm_write(&tags, sizeof(tiff_tag_t), entries, fmp); + out_le_u32(offset, offset); fm_write(&offset, sizeof(offset), 1, fmp); total_bytes_put += ifd_size; if (samples_per_pixel > 2) { + out_le_u16(bits_per_sample, bits_per_sample); for (i = 0; i < samples_per_pixel; i++) { fm_write(&bits_per_sample, sizeof(bits_per_sample), 1, fmp); } @@ -555,27 +552,29 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, const unsigned char *pix if (strip_count != 1) { /* Strip offsets */ for (i = 0; i < strip_count; i++) { - fm_write(&strip_offset[i], 4, 1, fmp); + out_le_u32(temp32, strip_offset[i]); + fm_write(&temp32, 4, 1, fmp); } /* Strip byte lengths */ for (i = 0; i < strip_count; i++) { - fm_write(&strip_bytes[i], 4, 1, fmp); + out_le_u32(temp32, strip_bytes[i]); + fm_write(&temp32, 4, 1, fmp); } total_bytes_put += strip_count * 8; } /* XResolution */ - temp32 = symbol->dpmm ? symbol->dpmm : 72; + out_le_u32(temp32, symbol->dpmm ? symbol->dpmm : 72); fm_write(&temp32, 4, 1, fmp); - temp32 = symbol->dpmm ? 10 /*cm*/ : 1; + out_le_u32(temp32, symbol->dpmm ? 10 /*cm*/ : 1); fm_write(&temp32, 4, 1, fmp); total_bytes_put += 8; /* YResolution */ - temp32 = symbol->dpmm ? symbol->dpmm : 72; + out_le_u32(temp32, symbol->dpmm ? symbol->dpmm : 72); fm_write(&temp32, 4, 1, fmp); - temp32 = symbol->dpmm ? 10 /*cm*/ : 1; + out_le_u32(temp32, symbol->dpmm ? 10 /*cm*/ : 1); fm_write(&temp32, 4, 1, fmp); total_bytes_put += 8; diff --git a/docs/README b/docs/README index d0788bda..ec7a24e3 100644 --- a/docs/README +++ b/docs/README @@ -1,3 +1,5 @@ +% docs/README 2014-01-17 + For generation of "docs/manual.pdf" and "docs/manual.txt" from "manual.pmd" using a recent version of pandoc On Ubuntu/Debian (tested on Ubuntu 22.04) diff --git a/frontend/tests/README b/frontend/tests/README index 01d0608f..d110f1f1 100644 --- a/frontend/tests/README +++ b/frontend/tests/README @@ -1,3 +1,5 @@ +% frontend/tests/README 2024-01-12 + Zint frontend test suite ------------------------ diff --git a/win32/README b/win32/README index 2b1c7805..46145ec1 100644 --- a/win32/README +++ b/win32/README @@ -1,3 +1,5 @@ +% win32/README 2024-01-17 + Visual Studio 2022 ------------------