| /* @(#) im_Lab2LabQ: quantise FLOAT Lab image into 10 11 11 format |
| * 4 bytes per pel: l a b lsbs |
| * this is an image wrapper which calls line-wise packing |
| * Copyright K.Martinez 3/5/93 |
| * Modified: |
| * 7/6/93 JC |
| * - adapted for partial v2 |
| * 5/5/94 JC |
| * - some nint->+0.5, for speed and to ease portability |
| * - other nint->rint |
| * - now inclues <math.h>! |
| * 15/11/94 JC |
| * - all nint(), rint() removed for speed |
| * - now -128 rather than -127 for a, b |
| * - checks input type properly |
| * 16/11/94 JC |
| * - uses new im_wrap_oneonebuf() |
| * 22/5/95 JC |
| * - changed L to scale by 10.24, not 10.23 |
| * 11/7/95 JC |
| * - now uses IM_RINT() for rounding |
| * 4/9/97 JC |
| * - L* = 100.0 now allowed |
| * 5/11/00 JC |
| * - go int earlier for speed up |
| * 20/6/02 JC |
| * - oops, were not clipping a/b range correctly |
| * 1/11/09 |
| * - gtkdoc |
| * - cleanups |
| */ |
| |
| /* |
| |
| This file is part of VIPS. |
| |
| VIPS is free software; you can redistribute it and/or modify |
| it under the terms of the GNU Lesser General Public License as published by |
| the Free Software Foundation; either version 2 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
| */ |
| |
| /* |
| |
| These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk |
| |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif /*HAVE_CONFIG_H*/ |
| #include <vips/intl.h> |
| |
| #include <stdio.h> |
| #include <math.h> |
| |
| #include <vips/vips.h> |
| |
| #ifdef WITH_DMALLOC |
| #include <dmalloc.h> |
| #endif /*WITH_DMALLOC*/ |
| |
| /* @(#) convert float Lab to packed Lab32 format 10 11 11 bits |
| * works only on buffers, not IMAGEs |
| * Copyright 1993 K.Martinez |
| * Modified: 3/5/93, 16/6/93 |
| */ |
| void |
| imb_Lab2LabQ( float *inp, unsigned char *outbuf, int n ) |
| { |
| float *f, fval; |
| int lsbs, intv; |
| int Xc; |
| unsigned char *out; |
| |
| out = outbuf; |
| f = inp; |
| for( Xc = 0; Xc < n; Xc++) { |
| /* Scale L up to 10 bits. Add 0.5 rather than call IM_RINT for |
| * speed. This will not round negatives correctly! But this |
| * does not matter, since L is >0. L*=100.0 -> 1023. |
| */ |
| intv = 10.23 * f[0] + 0.5; /* scale L up to 10 bits */ |
| if( intv > 1023 ) |
| intv = 1023; |
| if( intv < 0 ) |
| intv = 0; |
| lsbs = (intv & 0x3) << 6; /* 00000011 -> 11000000 */ |
| out[0] = (intv >> 2); /* drop bot 2 bits and store */ |
| |
| fval = 8.0 * f[1]; /* do a */ |
| intv = IM_RINT( fval ); |
| if( intv > 1023 ) |
| intv = 1023; |
| else if( intv < -1024 ) |
| intv = -1024; |
| |
| /* Break into bits. |
| */ |
| lsbs |= (intv & 0x7) << 3; /* 00000111 -> 00111000 */ |
| out[1] = (intv >> 3); /* drop bot 3 bits & store */ |
| |
| fval = 8.0 * f[2]; /* do b */ |
| intv = IM_RINT( fval ); |
| if( intv > 1023 ) |
| intv = 1023; |
| else if( intv < -1024 ) |
| intv = -1024; |
| |
| lsbs |= (intv & 0x7); |
| out[2] = (intv >> 3); |
| |
| out[3] = lsbs; /* store lsb band */ |
| |
| f += 3; |
| out += 4; |
| } |
| } |
| |
| /** |
| * im_Lab2LabQ: |
| * @in: input image |
| * @out: output image |
| * |
| * Convert a Lab three-band float image to LabQ (#IM_CODING_LABQ). |
| * |
| * See also: im_LabQ2Lab(). |
| * |
| * Returns: 0 on success, -1 on error. |
| */ |
| int |
| im_Lab2LabQ( IMAGE *in, IMAGE *out ) |
| { |
| IMAGE *t[1]; |
| |
| if( im_check_uncoded( "im_Lab2LabQ", in ) || |
| im_check_bands( "im_Lab2LabQ", in, 3 ) || |
| im_open_local_array( out, t, 1, "im_Lab2LabQ", "p" ) || |
| im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ) |
| return( -1 ); |
| |
| if( im_cp_desc( out, t[0] ) ) |
| return( -1 ); |
| out->Bands = 4; |
| out->Type = IM_TYPE_LAB; |
| out->BandFmt = IM_BANDFMT_UCHAR; |
| out->Coding = IM_CODING_LABQ; |
| |
| if( im_wrapone( t[0], out, |
| (im_wrapone_fn) imb_Lab2LabQ, NULL, NULL ) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |