Skip to content

Commit

Permalink
allow the API to be used from C++ and test for it
Browse files Browse the repository at this point in the history
this is backwards source incompatible, since the "virtual" member of
i_img was renamed to "isvirtual".  The i_img_virtual(someimage)
accessor works backward compatibly.
  • Loading branch information
tonycoz committed May 3, 2022
1 parent 0e4630a commit 6631fe3
Show file tree
Hide file tree
Showing 18 changed files with 161 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Imager.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4494,8 +4494,8 @@ sub Inline {
# Inline added a new argument at the beginning
my $lang = $_[-1];

$lang eq 'C'
or die "Only C language supported";
$lang eq 'C' || $lang eq 'CPP'
or die "Only C or C++ (CPP) language supported";

require Imager::ExtUtils;
return Imager::ExtUtils->inline_config;
Expand Down
5 changes: 5 additions & 0 deletions JPEG/Changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Imager-File-JPEG 0.96
=====================

- adapt to rename of i_img virtual member.

Imager-File-JPEG 0.95
=====================

Expand Down
2 changes: 1 addition & 1 deletion JPEG/JPEG.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use strict;
use Imager;

BEGIN {
our $VERSION = "0.95";
our $VERSION = "0.96";

require XSLoader;
XSLoader::load('Imager::File::JPEG', $VERSION);
Expand Down
2 changes: 1 addition & 1 deletion JPEG/imjpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ i_writejpeg_wiol(i_img *im, io_glue *ig, int qfactor) {

row_stride = im->xsize * im->channels; /* JSAMPLEs per row in image_buffer */

if (!im->virtual && im->type == i_direct_type && im->bits == i_8_bits
if (!i_img_virtual(im) && im->type == i_direct_type && im->bits == i_8_bits
&& im->channels == want_channels) {
image_buffer=im->idata;

Expand Down
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ t/400-filter/010-filters.t Consolidated filter tests (needs to split)
t/400-filter/020-autolevels.t Test the autolevels filter
t/450-api/100-inline.t Inline::C integration and API
t/450-api/110-inlinectx.t context APIs
t/450-api/130-cpp.t Inline::CPP integration and API
t/850-thread/010-base.t Test wrt to perl threads
t/850-thread/100-error.t error stack handling with threads
t/850-thread/110-log.t log handling with threads
Expand Down
14 changes: 13 additions & 1 deletion Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,11 @@ sub make_imconfig {
#ifndef IMAGER_IMCONFIG_H
#define IMAGER_IMCONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
EOS
for my $define (@$defines) {
if ($define->[2]) {
Expand Down Expand Up @@ -657,7 +662,14 @@ EOS
else {
print $config "#define IMAGER_STATIC_INLINE static\n";
}
print $config "\n#endif\n";
print $config <<'EOS';
#ifdef __cplusplus
}
#endif
#endif
EOS
close $config;
}

Expand Down
14 changes: 11 additions & 3 deletions imdatatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <stddef.h>
#include "imconfig.h"

#ifdef __cplusplus
extern "C" {
#endif

#define MAXCHANNELS 4

/*
Expand Down Expand Up @@ -267,7 +271,7 @@ for paletted images.
=item *
C<virtual> - if zero then this image is-self contained. If non-zero
C<isvirtual> - if zero then this image is-self contained. If non-zero
then this image could be an interface to some other implementation.
=item *
Expand Down Expand Up @@ -345,9 +349,9 @@ struct i_img_ {
unsigned int ch_mask;
i_img_bits_t bits;
i_img_type_t type;
int virtual; /* image might not keep any data, must use functions */
int isvirtual; /* image might not keep any data, must use functions */
unsigned char *idata; /* renamed to force inspection of existing code */
/* can be NULL if virtual is non-zero */
/* can be NULL if isvirtual is non-zero */
i_img_tags tags;

void *ext_data;
Expand Down Expand Up @@ -1196,5 +1200,9 @@ Casts two C<i_img_dim> values for use with the i_DF (or i_DFp) format.
#define i_DFcp(x, y) i_DFc(x), i_DFc(y)
#define i_DFp "%" i_DF ", %" i_DF

#ifdef __cplusplus
}
#endif

#endif

8 changes: 8 additions & 0 deletions imext.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include "imexttypes.h"
#include "immacros.h"

#ifdef __cplusplus
extern "C" {
#endif

extern im_ext_funcs *imager_function_ext_table;

#define DEFINE_IMAGER_CALLBACKS im_ext_funcs *imager_function_ext_table
Expand Down Expand Up @@ -258,4 +262,8 @@ extern im_ext_funcs *imager_function_ext_table;
#define mm_log(x)
#endif

#ifdef __cplusplus
}
#endif

#endif
8 changes: 8 additions & 0 deletions imexttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include "imdatatypes.h"
#include <stdarg.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
IMAGER_API_VERSION is similar to the version number in the third and
fourth bytes of TIFF files - if it ever changes then the API has changed
Expand Down Expand Up @@ -278,4 +282,8 @@ typedef struct {

#define PERL_FUNCTION_TABLE_NAME "Imager::__ext_func_table"

#ifdef __cplusplus
}
#endif

#endif
10 changes: 9 additions & 1 deletion immacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#ifndef IMAGER_IMMACROS_H_
#define IMAGER_IMMACROS_H_

#ifdef __cplusplus
extern "C" {
#endif

/*
=item i_img_has_alpha(C<im>)
Expand Down Expand Up @@ -112,7 +116,7 @@ returns -1 and pushes an error.
#define i_findcolor(im, color, entry) \
(((im)->i_f_findcolor) ? ((im)->i_f_findcolor)((im), (color), (entry)) : 0)

#define i_img_virtual(im) ((im)->virtual)
#define i_img_virtual(im) ((im)->isvirtual)
#define i_img_type(im) ((im)->type)
#define i_img_bits(im) ((im)->bits)

Expand Down Expand Up @@ -151,4 +155,8 @@ returns -1 and pushes an error.
#define io_new_cb(p, readcb, writecb, seekcb, closecb, destroycb) \
im_io_new_cb(aIMCTX, (p), (readcb), (writecb), (seekcb), (closecb), (destroycb))

#ifdef __cplusplus
}
#endif

#endif
8 changes: 8 additions & 0 deletions imperl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

#include "imdatatypes.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef i_color* Imager__Color;
typedef i_fcolor* Imager__Color__Float;
typedef i_img* Imager__ImgRaw;
Expand All @@ -28,4 +32,8 @@ typedef i_fill_t* Imager__FillHandle;

typedef io_glue *Imager__IO;

#ifdef __cplusplus
}
#endif

#endif
8 changes: 8 additions & 0 deletions iolayert.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include <stddef.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef enum { FDSEEK, FDNOSEEK, BUFFER, CBSEEK, CBNOSEEK, BUFCHAIN } io_type;

#ifdef _MSC_VER
Expand Down Expand Up @@ -107,4 +111,8 @@ struct i_io_glue_t {
#define i_io_error(ig) \
((ig)->read_ptr == (ig)->read_end && (ig)->error)

#ifdef __cplusplus
}
#endif

#endif
2 changes: 1 addition & 1 deletion lib/Imager/APIRef.pod
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ for paletted images.

=item *

C<virtual> - if zero then this image is-self contained. If non-zero
C<isvirtual> - if zero then this image is-self contained. If non-zero
then this image could be an interface to some other implementation.

=item *
Expand Down
2 changes: 1 addition & 1 deletion palimg.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ i_img_to_rgb_inplace(i_img *im) {
i_img temp;
dIMCTXim(im);

if (im->virtual)
if (i_img_virtual(im))
return 0;

if (im->type == i_direct_type)
Expand Down
2 changes: 1 addition & 1 deletion pnm.c
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ i_writeppm_wiol(i_img *im, io_glue *ig) {
return(0);
}

if (!im->virtual && im->bits == i_8_bits && im->type == i_direct_type
if (!i_img_virtual(im) && im->bits == i_8_bits && im->type == i_direct_type
&& im->channels == want_channels) {
if (i_io_write(ig,im->idata,im->bytes) != im->bytes) {
i_push_error(errno, "could not write ppm data");
Expand Down
2 changes: 1 addition & 1 deletion raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ i_writeraw_wiol(i_img* im, io_glue *ig) {
mm_log((1,"writeraw(im %p,ig %p)\n", im, ig));

if (im == NULL) { mm_log((1,"Image is empty\n")); return(0); }
if (!im->virtual) {
if (!i_img_virtual(im)) {
rc = i_io_write(ig,im->idata,im->bytes);
if (rc != im->bytes) {
i_push_error(errno, "Could not write to file");
Expand Down
80 changes: 80 additions & 0 deletions t/450-api/130-cpp.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!perl -w
#
# this tests the API headers are C++ compatible
use strict;
use Test::More;
eval "require Inline::CPP;";
plan skip_all => "Inline::CPP required for testing C++ compatibility" if $@;

use Cwd 'getcwd';
plan skip_all => "Inline won't work in directories with spaces"
if getcwd() =~ / /;

plan skip_all => "perl 5.005_04, 5.005_05 too buggy"
if $] =~ /^5\.005_0[45]$/;

-d "testout" or mkdir "testout";

print STDERR "Inline::CPP version $Inline::CPP::VERSION\n";

require Inline;
Inline->import(with => 'Imager');
Inline->import("FORCE"); # force rebuild
#Inline->import(C => Config => OPTIMIZE => "-g");

Inline->bind(CPP => <<'EOS');
#include <math.h>
int pixel_count(Imager::ImgRaw im) {
return im->xsize * im->ysize;
}
int count_color(Imager::ImgRaw im, Imager::Color c) {
int count = 0, x, y, chan;
i_color read_c;
for (x = 0; x < im->xsize; ++x) {
for (y = 0; y < im->ysize; ++y) {
int match = 1;
i_gpix(im, x, y, &read_c);
for (chan = 0; chan < im->channels; ++chan) {
if (read_c.channel[chan] != c->channel[chan]) {
match = 0;
break;
}
}
if (match)
++count;
}
}
return count;
}
Imager make_10x10() {
i_img *im = i_img_8_new(10, 10, 3);
i_color c;
c.channel[0] = c.channel[1] = c.channel[2] = 255;
i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &c);
return im;
}
EOS

my $im = Imager->new(xsize=>50, ysize=>50);
is(pixel_count($im), 2500, "pixel_count");

my $black = Imager::Color->new(0,0,0);
is(count_color($im, $black), 2500, "count_color black on black image");

my $im2 = make_10x10();
my $white = Imager::Color->new(255, 255, 255);
is(count_color($im2, $white), 100, "check new image white count");
ok($im2->box(filled=>1, xmin=>1, ymin=>1, xmax => 8, ymax=>8, color=>$black),
"try new image");
is(count_color($im2, $black), 64, "check modified black count");
is(count_color($im2, $white), 36, "check modified white count");


done_testing();
4 changes: 2 additions & 2 deletions tga.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ i_writetga_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idst

mm_log((1,"i_writetga_wiol(img %p, ig %p, idstring %p, idlen %ld, wierdpack %d, compress %d)\n",
img, ig, idstring, (long)idlen, wierdpack, compress));
mm_log((1, "virtual %d, paletted %d\n", img->virtual, mapped));
mm_log((1, "virtual %d, paletted %d\n", i_img_virtual(img), mapped));
mm_log((1, "channels %d\n", img->channels));

i_clear_error();
Expand Down Expand Up @@ -918,7 +918,7 @@ i_writetga_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idst
if (img->type == i_palette_type) {
if (!tga_palette_write(ig, img, bitspp, i_colorcount(img))) return 0;

if (!img->virtual && !dest.compressed) {
if (!i_img_virtual(img) && !dest.compressed) {
if (i_io_write(ig, img->idata, img->bytes) != img->bytes) {
i_push_error(errno, "could not write targa image data");
return 0;
Expand Down

0 comments on commit 6631fe3

Please sign in to comment.