-
-
Notifications
You must be signed in to change notification settings - Fork 646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VipsImage ref count in vips7 old style filters #3490
Comments
Hi @DavidStorm, We had to change this bit of API, unfortunately. The new thing is https://www.libvips.org/API/current/libvips-generate.html#vips-image-pipeline-array With This new call does a load of things:
|
Hi @jcupitt I tried to use This is a sample code: int
neo_LabQ2LabS( VipsImage *labim, VipsImage *outim )
{
if( im_cp_desc( outim, labim ) )
return( -1 );
outim->Bands = labim->Bands-1;
outim->Type = VIPS_INTERPRETATION_LABS;
outim->BandFmt = VIPS_FORMAT_SHORT;
outim->Bbits = IM_BBITS_SHORT;
outim->Coding = VIPS_CODING_NONE;
VIPS_SETSTR( outim->filename, labim->filename );
if( im_wrapone( labim, outim, (im_wrapone_fn)(outim->Bands == 3 ? _labQ2LabS : _labQ2LabS_withalpha ),
labim, outim) )
return( -1 );
return( 0 );
} The function int
im_wrapmany( IMAGE **in, IMAGE *out, im_wrapmany_fn fn, void *a, void *b )
{
...
vips__demand_hint_array( out, VIPS_DEMAND_STYLE_THINSTRIP, in );
if( vips__reorder_set_input( out, in ) )
return( -1 );
...
} a similar execution as int
vips_image_pipeline_array( VipsImage *image,
VipsDemandStyle hint, VipsImage **in )
{
vips__demand_hint_array( image, hint, in );
if( in[0] &&
vips__image_copy_fields_array( image, in ) )
return( -1 );
if( vips__reorder_set_input( image, in ) )
return( -1 );
return( 0 );
} Is it possible the problem is use VImage objets as wrapper of this filters? VImage neoLabQ2LabPS(VImage* input) noexcept(false)
{
VImage output;
int errorCode = neo_LabQ2LabPS(input->image(), output.image());
THROW_ERROR_IF_FAIL(errorCode);
return( output );
}
void main()
{
VImage in(“Sample.png");
in = neoLabQ2LabPS(&in);
} Thanks in advanced. |
I'd think that should work, but it's hard to tell from snippets of code, perhaps something else is happening. Could you make a complete, runnable example that shows the problem? Then I can test it instead of trying to fix it by looking at it. |
Sure. #include <vips/vips8>
#include <vips/vips7compat.h>
void
_Q2S(unsigned char* in, signed short* out, int n, void* ap, void* bp)
{
unsigned char* p = (unsigned char*)in;
signed short* q = (signed short*)out;
int i;
unsigned char ext;
signed short l, a, b;
for (i = 0; i < n; i++) {
/* Get most significant 8 bits of lab.
*/
l = p[0] << 7;
a = p[1] << 8;
b = p[2] << 8;
/* Get x-tra bits.
*/
ext = p[3];
p += 4;
/* Shift and mask in to lab.
*/
l |= (unsigned char)(ext & 0xc0) >> 1;
a |= (ext & 0x38) << 2;
b |= (ext & 0x7) << 5;
/* Write!
*/
q[0] = l;
q[1] = a;
q[2] = b;
q += 3;
}
}
int
_labQ2LabS(VipsImage* labim, VipsImage* outim)
{
if (labim->Coding != VIPS_CODING_LABQ) {
vips_error("neo_LabQ2LabS", " not a packed Lab image");
return(-1);
}
if (im_cp_desc(outim, labim))
return(-1);
outim->Bands = labim->Bands - 1;
outim->Type = VIPS_INTERPRETATION_LABS;
outim->BandFmt = VIPS_FORMAT_SHORT;
outim->Bbits = IM_BBITS_SHORT;
outim->Coding = VIPS_CODING_NONE;
VIPS_SETSTR(outim->filename, labim->filename);
if (im_wrapone(labim, outim, (im_wrapone_fn)(_Q2S),
labim, outim))
return(-1);
return(0);
}
int
main( int argc, char **argv )
{
int errorCode;
char srcPath[512] = "../Common/UnitTests/Images/ImageLABQ.tif";
char dstPath[512] = "../Common/UnitTests/Output/ImageLABS.tif";
vips::VImage dst = vips_image_new();
try
{
vips::VImage src = vips_image_new();
if (vips_format_read(srcPath, src.get_image()))
throw(-1);
errorCode = _labQ2LabS(src.get_image(), dst.get_image());
if (errorCode)
throw(-1);
}
catch(...)
{
}
errorCode = vips_image_write_to_file(dst.get_image(), dstPath, nullptr);
if (errorCode)
;
} |
I think you just need to call int
main( int argc, char **argv )
{
int errorCode;
if (VIPS_INIT(argv[0]))
throw(-1);
vips::VImage src = vips_image_new();
if (vips_format_read(argv[1], src.get_image()))
throw(-1);
vips::VImage dst = vips_image_new();
errorCode = _labQ2LabS(src.get_image(), dst.get_image());
if (errorCode)
throw(-1);
errorCode = vips_image_write_to_file(dst.get_image(), argv[2], nullptr);
if (errorCode)
throw(-1);
return(0);
} and it seems to work for me. |
Yes, I forget int
main( int argc, char **argv )
{
int errorCode;
if (VIPS_INIT(argv[0]))
return(-1);
vips::VImage dst = vips_image_new();
if (true)
{
vips::VImage src = vips_image_new();
if (vips_format_read(argv[1], src.get_image()))
return(-1);
errorCode = _labQ2LabS(src.get_image(), dst.get_image());
if (errorCode)
return(-1);
}
errorCode = vips_image_write_to_file(dst.get_image(), argv[2], nullptr);
if (errorCode)
throw(-1);
return(0);
} After execute the conditional, src image is destroyed but must be alive a refcount result of the filter |
I'll have a look. (you need to mark your code up like this:
to get it to display correctly ... a single back tick won't work) |
I don't think vips7 ever did refcounting, did it? That's one of the things we added in vips8 when we moved everything on top of gobject. You're mixing the vips8 C++ API (which uses vips8 refcounts) with the old vips7 API (no refcounts) and it's getting tangled up :( I would just use vips7 or just use vips8 and not mix them. |
Oh, or use the vips7 C++ API, but we don't support that any more, unfortunately. So ... I think I would suggest sticking with C++, but just just using the vips7 C API. |
Ok. It seems clear we have to update our filters from vips7 to vips8. Thanks for your help. |
vips7 stuff should still work -- nip2 (for example) has some built in vips7 filters and they work fine. You just can't mix the vips7 and vuips8 APIs (unless you are extremely careful). |
If I change your int
main( int argc, char **argv )
{
int errorCode;
if (VIPS_INIT(argv[0]))
return(-1);
IMAGE *src = im_open("temp", "p");
if (vips_format_read(argv[1], src))
return(-1);
IMAGE *dst = im_open("temp", "p");
errorCode = _labQ2LabS(src, dst);
if (errorCode)
return(-1);
im_close(src);
errorCode = vips_image_write_to_file(dst, argv[2], nullptr);
if (errorCode)
throw(-1);
im_close(dst);
return(0);
} It still works. It can write |
Good to know. Thanks. |
I’m updating libvips from 8.12 to last 8.15 version.
I have a lot of filters in old vips7 style like:
but we don’t connect both images and reference count as new style vips8.
In this sequence:
function
vips_image_write_to_file()
crashes because in and out are not connected.How can I connect ‘in' image to ‘out’ image and ref count to process or save ‘out’ in other part of my application?.
I saw functions as
vips__object_set_member()
orvips_operation_set_valist_required()
used to connect in-out images in vips filters, but is not clear how to use.The text was updated successfully, but these errors were encountered: