In my NC30 M16C compiler version 5, I had the following macros used by previous programmer. We use this macros in the "printf()", "sprintf()" etc functions.
typedef unsigned char * va_list;
#define va_start( args, first ) args = (va_list) ( (unsigned short) &first + sizeof( first ) )
#define va_arg( args, type ) *( (type *) args )++
#define va_end( args )
When I compile this code with NC30 M16C compiler version 6, then it is giving me the error "Invalid lvalue".
Here is the part of the entire error message:
clib.c(253) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned int );
clib.c(293) : C2700 (E) invalid lvalue
===> fch = va_arg( args, far char * );
clib.c(299) : C2700 (E) invalid lvalue
===> nch = va_arg( args, char * );
clib.c(305) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned int );
clib.c(323) : C2700 (E) invalid lvalue
===> ulong = va_arg( args, unsigned long );
clib.c(341) : C2700 (E) invalid lvalue
===> llong = va_arg( args, unsigned long long );
clib.c(359) : C2700 (E) invalid lvalue
===> ulong = va_arg( args, unsigned long );
clib.c(377) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned short );
clib.c(382) : C2700 (E) invalid lvalue
===> ft = va_arg( args, float );
clib.c(519) : C2694 (E) unknown variable source
===> *source++ = zeropad ? '0' : ' ';
clib.c(527) : C2694 (E) unknown variable source
===> *source++ = '%';
clib.c(532) : C2700 (E) invalid lvalue
===> snum = va_arg( args, signed int );
clib.c(550) : C2694 (E) unknown variable source
===> *source++ = *tempptr;
clib.c(556) : C2700 (E) invalid lvalue
===> fch = va_arg( args, far char * );
clib.c(558) : C2694 (E) unknown variable source
===> *source++ = *fch++;
clib.c(564) : C2700 (E) invalid lvalue
===> nch = va_arg( args, char * );
clib.c(566) : C2694 (E) unknown variable source
===> *source++ = *nch++;
clib.c(572) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned int );
Here is one of the function in which we have used these micros. This function is the same function as "printf" but named it zwPrintf():
int zwPrintf( far char * format, ... ) {
zwVAList args;
unsigned int unum;
unsigned char temp[ FIELD_BUFF_SIZE + 1 ]; /* for formatting numbers (max length for long decimal) */
unsigned char * tempptr;
int zeropad, minfield, counter;
far char * fch;
char * nch;
unsigned long ulong;
int negative;
float ft, mantissa;
unsigned long long llong;
//unsigned char mychar;
//unsigned char *mychar_p;
//unsigned int *mytest_p;
va_start( args, format );
while( *format ) {
if( *format == '%' ) {
format++;
zeropad = 0;
minfield = 0;
negative = 0;
if( *format == '0' )
zeropad = 1; /* we want zero padding to field width */
while( *format >= '0' && *format <= '9' ) {
/* we are specifying field width */
minfield *= 10;
minfield += *format - '0';
format++;
}
if( minfield > FIELD_BUFF_SIZE ) { /* we want a field width greater than our field buffer, pad misc */
for( counter = 0; counter < minfield - FIELD_BUFF_SIZE; counter++ )
zwPutc( (unsigned char) ( zeropad ? '0' : ' ' ) );
minfield = FIELD_BUFF_SIZE;
}
switch( *format ) {
case '%': /* literal % */
zwPutc( '%' );
break;
case 'd': /* signed decimal output */
unum = va_arg( args, unsigned int ); /* pull unsigned, and do math ourselves (to avoid confusion) */
//mychar='a';
//mychar_p = &mychar;
//mytest_p = ((unsigned int*)mychar_p);
//mytest_p++;
//unum = *mytest_p;
//unum = (*((unsigned int*)args))++;
//unum = (*((unsigned int*)args))++;
/* convert to decimal (backward) */
if( unum >= 0x8000 ) { /* number is -'ve */
negative = 1;
unum = ~unum + 1; /* make number +'ve */
}
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( unum )
*tempptr-- = ( unum % 10 ) + '0';
else {
if( negative && ( zeropad == 0 ) ) {
*tempptr-- = '-';
negative = 0;
}
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
}
unum /= 10;
counter++;
} while( unum || counter < minfield );
/* output the string */
if( negative )
zwPutc( '-' );
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 's': /* far char * */
fch = va_arg( args, far char * );
while( *fch )
zwPutc( *fch++ );
break;
case 'S': /* near char * (extension) */
nch = va_arg( args, char * );
while( *nch )
zwPutc( *nch++ );
break;
case 'x': /* hexadecimal */
unum = va_arg( args, unsigned int );
/* convert to hexadecimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( unum )
*tempptr-- = zwHexToAsc( (unsigned char) unum & 0x0F );
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
unum >>= 4;
counter++;
} while( unum || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'i': /* unsigned long int decimal (extension) */
ulong = va_arg( args, unsigned long );
/* convert to decimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( ulong )
*tempptr-- = (unsigned char)( ulong % 10 ) + '0';
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
ulong /= 10;
counter++;
} while( ulong || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'L': /* unsigned long long decimal (extension) */
llong = va_arg( args, unsigned long long );
/* convert to decimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( llong )
*tempptr-- = (unsigned char)( llong % 10 ) + '0';
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
llong /= 10;
counter++;
} while( llong || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'h': /* unsigned long int hexadecimal (extension) */
ulong = va_arg( args, unsigned long );
/* convert to hexadecimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( ulong )
*tempptr-- = zwHexToAsc( ( (unsigned char) ulong ) & 0x0F );
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
ulong >>= 4;
counter++;
} while( ulong || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'c':
unum = va_arg( args, unsigned short );
zwPutc( (char) unum );
break;
case 'f':
ft = va_arg( args, float );
#if 0
/* convert to decimal (backward) */
if( ft < 0 ) { /* number is -'ve */
negative = 1;
ft = -ft;
}
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
/* split float to integer and mantissa part */
ulong = ft / 1;
mantissa = ft - ( float )ulong;
/* get integer part */
do {
if( ulong ){
*tempptr-- = (unsigned char)( ulong % 10 ) + '0';
}
else {
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
}
ulong /= 10;
counter++;
} while( ulong || counter < minfield );
if ( negative ) {
temp[ 0 ] = '-';
zwMemcpy( &temp[ 1 ], &temp[ FIELD_BUFF_SIZE - counter ], counter ); //change to right position
counter++;
}
else
zwMemcpy( &temp[ 0 ], &temp[ FIELD_BUFF_SIZE - counter ], counter );
temp[ counter++ ] = '.';
/* get mantissa part */
tempptr = &temp[ counter ];
do {
unum = ( mantissa * 10 ) / 1;
if( unum ){
*tempptr++ = (unsigned char)( unum ) + '0';
}
else {
*tempptr++ = '0';
}
mantissa = ( float ) ( mantissa * 10.0 - ( float )unum ) * 10.0;
counter++;
} while( mantissa > 0 || counter < minfield );
for( unum = 0; unum < counter; unum++ )
zwPutc( temp[ unum ] );
/* convert to decimal (backward) */
if( ft < 0 ) { /* number is -'ve */
negative = 1;
ft = -ft;
}
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( ft >= 1.0 ){
*tempptr-- = ( ft % 10.0 ) + '0';
// *tempptr-- = ( ft * 10 - ( ( ft * 100 ) / 10 ) ) + '0';
}
else {
if( negative && ( zeropad == 0 ) ) {
*tempptr-- = '-';
negative = 0;
}
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
}
ft /= 10;
counter++;
} while( ft >= 1.0 || counter < minfield );
/* output the string */
if( negative )
zwPutc( '-' );
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
#endif
break;
case 0: /* end of string (malformed string anyway) */
va_end( args );
return -1; /* error */
break;
}
}
else
zwPutc( *format );
format++;
}
va_end( args );
return -1;
}
Please guide me, what should I do to correct this issue.
Thanks in advance.
Could you try to replace:
#define va_arg( args, type ) *( (type *) args )++
with
#define va_arg( args, type ) *( (type *) args ), args += sizeof (type)
Explanation:
You get the compilation error because this expression:
((type *) args )++
is invalid in C: the result of a cast is not a lvalue and the postfix ++ operator requires its operand to be a lvalue. A lot of compilers are lax with this constraint but apparently yours is not (or the new version is stricter).
Also note that the proposed workaround should work in you program with simple assignment expressions like:
unum = va_arg( args, unsigned int );
because = has higher precedence than the comma operator.
EDIT:
another (maybe even better) solution: you should be able to bypass the fact the result of a cast is not a lvalue using this solution:
#define va_arg( args, type ) *( *(type **) &args )++
Related
I am attempting to create a Worley Noise function. I looked around and read the original paper by Steven Worley and wrote my implementation. The output does not appear to be correct though. I expect to see something like this.
But it outputs this.
I'm not sure what I am doing wrong. I have looked online at other peoples programs and I do it the same way. Here is the code.
float WorleyNoise::noise( Vector3 input ) {
unsigned int lastRandom;
unsigned int numberFeaturePoints;
Vector3 randomDiff;
Vector3 featurePoint;
int cubeX;
int cubeY;
int cubeZ;
float distanceArray[ 3 ];
for ( int i = 0; i < 3; i++ ) {
distanceArray[ i ] = 6666.0f;
}
int evalX = ( int ) floorf( input.m_x );
int evalY = ( int ) floorf( input.m_y );
int evalZ = ( int ) floorf( input.m_z );
for ( int i = -1; i < 2; ++i ) {
for ( int j = -1; j < 2; ++j ) {
for ( int k = -1; k < 2; ++k ) {
cubeX = evalX + i;
cubeY = evalY + j;
cubeZ = evalZ + k;
lastRandom = lcg_random( hash( ( unsigned int ) ( cubeX + m_seed ), ( unsigned int ) cubeY, ( unsigned int ) cubeZ ) );
numberFeaturePoints = lookup( lastRandom );
for ( unsigned int l = 0; l < numberFeaturePoints; ++l ) {
lastRandom = lcg_random( lastRandom );
randomDiff.m_x = ( float ) lastRandom / 0x100000000;
lastRandom = lcg_random( lastRandom );
randomDiff.m_y = ( float ) lastRandom / 0x100000000;
lastRandom = lcg_random( lastRandom );
randomDiff.m_z = ( float ) lastRandom / 0x100000000;
featurePoint.m_x = randomDiff.m_x + ( float ) cubeX;
featurePoint.m_y = randomDiff.m_y + ( float ) cubeY;
featurePoint.m_z = randomDiff.m_z + ( float ) cubeZ;
insert( distanceArray, euclidian_distance( input, featurePoint ) );
}
}
}
}
return Utility::clampf( combine_function_1( distanceArray ), 0.0f, 1.0f );
}
unsigned int WorleyNoise::hash( unsigned int i, unsigned int j, unsigned int k ) {
return ( unsigned int ) ( ( ( ( ( ( OFFSET_BASIS ^ ( unsigned int ) i ) * FNV_PRIME ) ^ ( unsigned int ) j ) * FNV_PRIME ) ^ ( unsigned int ) k ) * FNV_PRIME );
}
unsigned int WorleyNoise::lcg_random( unsigned int last ) {
return ( unsigned int ) ( ( 1103515245 * last + 12345 ) % 0x100000000 );
}
void WorleyNoise::insert( float arr[] , float value ) {
float temp = 0.0f;
for ( int i = 2; i >= 0; i-- ) {
if ( value > arr[ i ] ) {
break;
}
temp = arr[ i ];
arr[ i ] = value;
if ( i + 1 < 3 ) {
arr[ i + 1 ] = temp;
}
}
}
unsigned int WorleyNoise::lookup( unsigned int value ) {
value = value & 0xffffffff;
if ( value < 393325350 )
return 1;
if ( value < 1022645910 )
return 2;
if ( value < 1861739990 )
return 3;
if ( value < 2700834071 )
return 4;
if ( value < 3372109335 )
return 5;
if ( value < 3819626178 )
return 6;
if ( value < 4075350088 )
return 7;
if ( value < 4203212043 )
return 8;
return 9;
}
float WorleyNoise::euclidian_distance( Vector3 p1, Vector3 p2 ) {
return ( p1.m_x - p2.m_x ) * ( p1.m_x - p2.m_x ) + ( p1.m_y - p2.m_y ) * ( p1.m_y - p2.m_y ) + ( p1.m_z - p2.m_z ) * ( p1.m_z - p2.m_z );
}
float WorleyNoise::combine_function_1( float arr[] ) {
return arr[ 0 ];
}
I then output the results like so with pngwriter.
void WorleyNoise::to_png( const std::string &file, unsigned int width, unsigned int height ) {
pngwriter png( width, height, 0, file.c_str() );
for ( unsigned int i = 0; i < width; i++ ) {
for ( unsigned int j = 0; j < height; j++ ) {
float value = noise( Vector3( i, j, 0 ) );
png.plot( i, j, ( double ) value, ( double ) value, ( double ) value );
}
}
png.close();
}
So what is going wrong here? I've looked all over, especially at this tutorial and cannot figure out why it does not output correctly. Any help is greatly appreciated, thanks.
Below screen shot is the result of the execution of the function in MATLAB.
a=imread('C:\CVIPtools\images\car.bmp');
ad=im2double(a);
ht = halftoneCVIP(ad,4,255, 0.5, 0, 0);
Halftoning: it's a methods for reducing the number of gray levels by creating dot patterns or dither patterns to represent various gray levels, reduces effective spatial resolution also.
There are 6 methods in halftoning.
1. Floyd Stienberg
2. Dither
3. Threshold
4. Cluster 3
5. Cluster 4
6. Cluster 8
*Image *CVIPhalftone(Image cvip_Image, int halftone, int
maxval, float fthreshval, CVIP_BOOLEAN retain_image,
CVIP_BOOLEAN verbose)
<cvip_Image> - pointer to input image
<halftone> - indicates method used to convert from grays-
cale to binary. (one of QT_FS, QT_THRESH, QT_DITHER8,
QT_CLUSTER3, QT_CLUSTER4, QT_CLUSTER8)
<maxval> - specifies maximum range of input image (usually
255)
<fthreshval> - threshold value (for QT_THRESH) between [0.0
... 1.0].
<retain_image> - retain image after writing (CVIP_YES or
CVIP_NO)?
<verbose> - shall I be verbose (CVIP_YES or CVIP_NO)?**
I am trying to reuse a halftone function origianlly written in C. My objective is to make this function executable in MATLAB by writing a wrapper function using MEX.
Below are the code I have written and I am able to compile successfully without any errors. However, while executing the function MATLAB crashes. Does anyone know the reason behind this?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "mex.h"
#include "CVIPtools.h"
#include "CVIPimage.h"
#include "CVIPdef.h"
#include "CVIPmap.h"
#include "limits.h"
#include "threshold.h"
#include <float.h>
#include "CVIPmatrix.h"
#include "dithers.h"
#include "CVIPhalftone.h"
#define CVIP_WHITE 1
#define CVIP_BLACK 0
#define FS_SCALE 1024
#define HALF_FS_SCALE 512
Image *CVIPhalftone(Image *cvip_Image, int halftone, int maxval, float fthreshval, CVIP_BOOLEAN retain_image, CVIP_BOOLEAN verbose)
{
byte* grayrow;
register byte* gP;
byte* bitrow;
register byte* bP;
int rows, cols, row;
int col, limitcol, format;
char function_name[] = {"CVIPhalftone"};
long threshval, sum;
long* thiserr;
long* nexterr;
long* temperr;
int fs_direction;
Image *bit_Image;
cols = cvip_Image->image_ptr[0]->cols;
rows = cvip_Image->image_ptr[0]->rows;
bit_Image = (Image *) image_allocate(cvip_Image->image_format, BINARY, 1, rows, cols, CVIP_BYTE, REAL);
format = cvip_Image->image_format;
if( !(format==PBM || format==PGM || format==TIF || format==RAS || format==BIN || format==ITX) ) {
if(verbose)
fprintf(stderr, "\n%s: casting image to format that supports binary images - (PBM).\n",function_name);
bit_Image->image_format = PBM;
}
mexPrintf("Till here 1\n");
/* Initialize. */
switch ( halftone )
{
case QT_FS: // QT_FS=1 defined in CVIPhalftone.h
if(verbose)
fprintf(stderr, "%s: performing boustrophedonic Floyd-Steinberg error diffusion.\n\n",function_name);
/* Initialize Floyd-Steinberg error vectors. */
thiserr = (long*) calloc( cols + 2, sizeof(long) );
nexterr = (long*) calloc( cols + 2, sizeof(long) );
srand( (int) ( time( 0 ) ^ getpid( ) ) );
for ( col = 0; col < cols + 2; ++col )
thiserr[col] = ( rand( ) % FS_SCALE - HALF_FS_SCALE ) / 4;
/* (random errors in [-FS_SCALE/8 .. FS_SCALE/8]) */
fs_direction = 1;
threshval = fthreshval * FS_SCALE;
break;
case QT_THRESH: // QT_THRESH=2 defined in CVIPhalftone.h
threshval = fthreshval * maxval + 0.999999;
if(verbose) {
fprintf(stderr, "%s: performing simple thresholding operation.\n",function_name);
fprintf(stderr, "%s: threshold level - %ld.\n\n",function_name, threshval);
}
break;
case QT_DITHER8: // QT_DITHER8=3 defined in CVIPhalftone.h
break;
case QT_CLUSTER3: // QT_CLUSTER3=4 defined in CVIPhalftone.h
break;
case QT_CLUSTER4: // QT_CLUSTER4=5 defined in CVIPhalftone.h
break;
case QT_CLUSTER8: // QT_CLUSTER8=6 defined in CVIPhalftone.h
break;
default:
fprintf(stderr, "%s: can't happen... but apparently something did?!?\n" , function_name); break;
}
mexPrintf("Till here 2\n");
for ( row = 0; row < rows; ++row )
{
grayrow = (byte *) ((byte **) cvip_Image->image_ptr[0]->rptr)[row];
bitrow = (byte *) ((byte **) bit_Image->image_ptr[0]->rptr)[row];
switch ( halftone )
{
case QT_FS:
for ( col = 0; col < cols + 2; ++col )
nexterr[col] = 0;
if ( fs_direction )
{
col = 0;
limitcol = cols;
gP = grayrow;
bP = bitrow;
}
else
{
col = cols - 1;
limitcol = -1;
gP = &(grayrow[col]);
bP = &(bitrow[col]);
}
do
{
sum = ( (long) *gP * FS_SCALE ) / maxval + thiserr[col + 1];
if ( sum >= threshval )
{
*bP = CVIP_WHITE;
sum = sum - threshval - HALF_FS_SCALE;
}
else
*bP = CVIP_BLACK;
if ( fs_direction )
{
thiserr[col + 2] += ( sum * 7 ) / 16;
nexterr[col ] += ( sum * 3 ) / 16;
nexterr[col + 1] += ( sum * 5 ) / 16;
nexterr[col + 2] += ( sum ) / 16;
++col;
++gP;
++bP;
}
else
{
thiserr[col ] += ( sum * 7 ) / 16;
nexterr[col + 2] += ( sum * 3 ) / 16;
nexterr[col + 1] += ( sum * 5 ) / 16;
nexterr[col ] += ( sum ) / 16;
--col;
--gP;
--bP;
}
}
while ( col != limitcol );
temperr = thiserr;
thiserr = nexterr;
nexterr = temperr;
fs_direction = ! fs_direction;
break;
case QT_THRESH:
for ( col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP )
if ( *gP >= threshval )
*bP = CVIP_WHITE;
else
*bP = CVIP_BLACK;
break;
case QT_DITHER8:
for ( col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP )
if ( *gP >= dither8[row % 16][col % 16] * ( maxval + 1 ) / 256 )
*bP = CVIP_WHITE;
else
*bP = CVIP_BLACK;
break;
case QT_CLUSTER3:
for ( col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP )
if ( *gP >= cluster3[row %6][col %6 ] * ( maxval + 1 ) / 18 )
*bP = CVIP_WHITE;
else
*bP = CVIP_BLACK;
break;
case QT_CLUSTER4:
for ( col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP )
if ( *gP >= cluster4[row %8][col%8] * ( maxval + 1 ) / 32 )
*bP = CVIP_WHITE;
else
*bP = CVIP_BLACK;
break;
case QT_CLUSTER8:
for ( col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP )
if ( *gP >= cluster8[row %16][col %16] * ( maxval + 1 ) / 128 )
*bP = CVIP_WHITE;
else
*bP = CVIP_BLACK;
break;
default:
fprintf(stderr, "%s: can't happen... but apparently something did?!?\n" , function_name); break;
}
}
mexPrintf("Till here 1\n");
if(!retain_image)
image_free(cvip_Image);
return bit_Image;
mexPrintf("Till here 2\n");
}
void midd( int choice, double *indata, double *outdata, int n, int row, int col, int bands)
{
Image *inputImage;
byte **image;
unsigned int r, c;
int i;
unsigned int no_of_rows,
no_of_cols,
no_of_bands;
COLOR_FORMAT color_space;
int check=0;
no_of_bands = bands;
no_of_rows = row;
no_of_cols = col;
for (i=0;i<n;i++)
{ if (check<indata[i])
check=indata[i];
}
if (check<=1){
for (i=0;i<n;i++){
//outdata[i]= floor(255*indata[i]); //By Krishna Regmi
indata[i]= floor(255*indata[i]);
}}
else
{for (i=0;i<n;i++)
//outdata[i]= floor(indata[i]); //By Krishna Regmi
indata[i]= floor(indata[i]);
}
// mexPrintf("\ first value after scaling to 0-255 %f\n", outdata[0]);
// typedef enum {PBM, PGM, PPM, EPS, TIF, GIF, RAS, ITX, IRIS, CCC, BIN, VIP, GLR, BTC, BRC, HUF, ZVL, ARITH, BTC2, BTC3, DPC, ZON, ZON2, SAFVR, JPG, WVQ, FRA, VQ, XVQ} IMAGE_FORMAT;
//typedef enum {BINARY, GRAY_SCALE, RGB, HSL, HSV, SCT, CCT, LUV, LAB, XYZ}
inputImage=new_Image (BMP, RGB, no_of_bands, row, col, CVIP_BYTE, REAL );
for(bands=0; bands < no_of_bands; bands++) {
image = getData_Image(inputImage, bands);
for(r=0; r < no_of_rows; r++) {
for(c=0; c < no_of_cols; c++)
{
image[r][c]=outdata[r+row*c+row*col*bands]; /* passing data from MATLAB variable to CVIPtools variable */
}
}
}
//Image *CVIPhalftone(Image *cvip_Image, int halftone, int maxval, float fthreshval, CVIP_BOOLEAN retain_image, CVIP_BOOLEAN verbose)
//inputImage= CVIPhalftone(cvipImage,QT_THRESH,255,0.5,CVIP_NO,CVIP_NO);
inputImage = CVIPhalftone(inputImage, choice, 255, 0.5, CVIP_NO, CVIP_NO);
for(bands=0; bands < no_of_bands; bands++) {
image = getData_Image(inputImage, bands);
for(r=0; r < no_of_rows; r++) {
for(c=0; c < no_of_cols; c++)
{
outdata[r+row*c+row*col*bands] = floor(image[r][c]); /* passing data back to MATLAB variable from CVIPtools variable */
}
}
}
} /* end of wrapper function*/
/* main gateway function*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *outdata, *indata;
int r,c,bands;
const mwSize *dim_array;
int choice,n;
//char color_type;
// COLOR_FORMAT color_space;
//int choice;
//int n = mxGetNumberOfElements(prhs[0]);
n = mxGetNumberOfElements(prhs[0]);
indata = mxGetData(prhs[0]);
//double *indata = (double *)mxGetData(prhs[0]);
dim_array = mxGetDimensions(prhs[0]);
//color_type = mxGetChars(prhs[1]);
choice = mxGetScalar(prhs[1]);
r = dim_array[0];
c = dim_array[1];
bands = dim_array[2];
// mexPrintf("total elements %d\n", n);
if(bands==3){
plhs[0] = mxCreateNumericArray(3, dim_array, mxDOUBLE_CLASS, mxREAL);
}
else
{ plhs[0] = mxCreateDoubleMatrix(r,c,mxREAL);
bands=1;
}
outdata = mxGetData(plhs[0]);
midd(choice, indata, outdata, n, r, c, bands);
}
Sounds like a segmentation fault in your mex code. Check the input datatypes. Make sure that the data type of the parameters passed from matlab match those that are expected by the C function. Also, keep in mind that matlab arrays are column-major, and the sizes are [rows, cols], not [width height].
If you can't spot the problem easily, then you would need to attach a debugger to the matlab process, or add a lot of mexPrintf's into your code to see where exactly it fails.
How would it be possible to feed the TEA cipher without exceeding a systems ram with large files?
I have tried doing this however it has all ended with massive failure and hours of tinkering that leads to nothing. So could someone give me an example of how this can be done or any meaningful information on how to do it?
void decodeXtea(unsigned int* v, unsigned int* w, unsigned int* k) {
register unsigned int v0=v[0], v1=v[1], i, sum=0xC6EF3720;
register unsigned int delta=0x9E3779B9;
for(i=0; i<32; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
}
w[0]=v0; w[1]=v1;
}
void TeaDecode ( const std::string& str, const std::string& key, std::string* out )
{
unsigned int v[2];
unsigned int w[2];
unsigned int k[4];
unsigned int keybuffer [ 4 ];
// Clear buffers
memset ( v, 0, sizeof(v) );
memset ( w, 0, sizeof(w) );
memset ( k, 0, sizeof(k) );
memset ( keybuffer, 0, sizeof(keybuffer) );
out->clear ();
// Count the number of passes that we need
int numBlocks = str.length() / 4;
int numPasses = numBlocks - 1;
if ( numPasses <= 0 )
return;
// Process the key
int len = key.length ();
if ( len > 16 )
len = 16;
memcpy ( keybuffer, key.c_str(), len );
for ( int i = 0; i < 4; ++i )
k[i] = keybuffer[i];
// Create a temporary buffer to store the result
unsigned char* buffer = new unsigned char [ numPasses * 4 + 4 ];
memset ( buffer, 0, numPasses * 4 + 4 );
// Decode it!
const char* p = str.c_str();
v[1] = *(unsigned int*)&p[numPasses * 4];
for ( int i = 0; i < numPasses; ++i )
{
v[0] = *(unsigned int*)&p[(numPasses-i-1)*4];
decodeXtea ( &v[0], &w[0], &k[0] );
*(unsigned int*)&buffer[(numPasses-i-1)*4] = w[0];
v[1] = w[1];
}
out->assign ( (char *)buffer, numPasses*4 );
delete [] buffer;
}
void encodeXtea(unsigned int* v, unsigned int* w, unsigned int* k) {
register unsigned int v0=v[0], v1=v[1], i, sum=0;
register unsigned int delta=0x9E3779B9;
for(i=0; i<32; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
}
w[0]=v0; w[1]=v1;
}
void TeaEncode ( const std::string& str, const std::string& key, std::string* out )
{
unsigned int v[2];
unsigned int w[2];
unsigned int k[4];
unsigned int keybuffer [ 4 ];
// Clear buffers
memset ( v, 0, sizeof(v) );
memset ( w, 0, sizeof(w) );
memset ( k, 0, sizeof(k) );
memset ( keybuffer, 0, sizeof(keybuffer) );
out->clear ();
// Process the key
int len = key.length ();
if ( len > 16 )
len = 16;
memcpy ( keybuffer, key.c_str(), len );
for ( int i = 0; i < 4; ++i )
k[i] = keybuffer[i];
// Copy the input string to a buffer of size multiple of 4
int strbuflen = str.length ();
if ( strbuflen == 0 )
return;
if ( (strbuflen % 4) > 0 )
strbuflen += 4 - (strbuflen % 4);
unsigned char* strbuf = new unsigned char [ strbuflen ];
memset ( strbuf, 0, strbuflen );
memcpy ( strbuf, str.c_str(), str.length() );
// Encode it!
v[1] = 0;
for ( int i = 0; i < strbuflen; i += 4 )
{
v[0] = *(unsigned int*)&strbuf[i];
encodeXtea ( &v[0], &w[0], &k[0] );
out->append ( (char*)&w[0], 4 );
v[1] = w[1];
}
out->append ( (char*)&v[1], 4 );
delete [] strbuf;
}
This fixed it.
void readSystem(string fname,string outFileName,string key,string mode)
{
//size_t buffer_size = 1<<20;
size_t buffer_size;
if(mode == "E")
{
buffer_size = 32;
}
else
{
buffer_size = 36;
}
//char *buffer = new char[buffer_size];
string buffer(buffer_size,'\0');
string data,output;
//data.resize(buffer_size);
// The input
std::ifstream fin(fname,ios::binary);
// The output
ofstream outFile(outFileName,ios::binary);// | ios::app);
// Anti overwrite
if(getSize(outFileName) > 0)
{
cout << "Overwrite error" << endl;
exit(0);
}
while (fin)
{
// Try to read next chunk of data
// fin.read(buffer, buffer_size);
fin.read(&buffer.front(), buffer_size);
// Get the number of bytes actually read
size_t count = fin.gcount();
data = buffer;
//data = encode(data,key);
if(mode == "E")
{
data = encode(data,key);
}
if(mode == "D")
{
data = decode(data,key);
}
//blockXor(data,key);
//outFile.write(data.c_str(),count);
outFile.write(data.c_str(),data.length());
// If nothing has been read, break
if (!count)
break;
// Do whatever you need with first count bytes in the buffer
}
outFile.close();
fin.close();
// delete[] buffer;
}
I am looking to convert existing code in C to perform the following: I am attempting to write a hex dump program that prints out address: values printable characters.
Currently, the code for values is printing in the following format:
0003540: 05 04 06 75 6e 73 69 67 6e 65 64 20 63 68 61 72 ...unsigned char
Desired hex output:
0003540: 0504 0675 6e73 6967 6e65 6420 6368 6172 ...unsigned char
Current code printing in pairs:
addr = 0;
while ( ( cnt = ( long )
fread ( buf, sizeof ( unsigned char ), 16, filein ) ) > 0 ) {
b = buf;
/* Print the address in hexadecimal. */
fprintf ( fileout, "%07lx ", addr );
addr = addr + 16;
/* Print 16 data items, in pairs, in hexadecimal. */
cnt2 = 0;
for ( m = 0; m < 16; m++ ) {
cnt2 = cnt2 + 1;
if ( cnt2 <= cnt ) {
fprintf ( fileout, "%02x", *b++ );
}
else {
fprintf ( fileout, " " );
}
fprintf ( fileout, " " );
}
/* Print the printable characters, or a period if unprintable. */
fprintf ( fileout, " " );
cnt2 = 0;
for ( n = 0; n < 16; n++ ) {
cnt2 = cnt2 + 1;
if ( cnt2 <= cnt ) {
if ( ( buf[n] < 32 ) || ( buf[n] > 126 ) ) {
fprintf ( fileout, "%c", '.' );
}
else {
fprintf ( fileout, "%c", buf[n] );
}
}
}
fprintf( fileout, "\n" );
}
How can I alter this code to achieve the AB12 CD34 format?
Thanks!
Use the modulo (remainder) operator % to test if m is divisible by 2. Only write the space when it is:
for ( m = 0; m < 16; m++ ) {
if ( m > 0 && m % 2 == 0 ) {
fprintf ( fileout, " " );
}
fprintf ( fileout, "%02x", *b++ );
}
Edit 3:
for ( m = 0; m < 16; m++ ) {
if ( m > 0 && m % 2 == 0 ) {
fprintf ( fileout, " " ); // space between every second byte
}
if ( m < cnt ) {
fprintf ( fileout, "%02x", *b++ );
} else {
fprintf ( fileout, " " ); // blank if run out of bytes on this line
}
}
I think this can be simplified quite a bit. For example, I'd consider starting with something like this:
#include <stdio.h>
#include <ctype.h>
int main(){
char buffer[17];
size_t bytes;
int i;
while (0 < (bytes = fread(buffer, 1, 16, stdin))) {
for (i = 0; i < bytes / 2; i++) // print out bytes, 2 at a time
printf("%02x%02x ", buffer[i * 2], buffer[i * 2 + 1]);
if (i * 2 < bytes) // take care of (possible) odd byte
printf("%02x ", buffer[i * 2]);
for (; i < 8; i++) // right pad hex bytes
printf(" ");
for (i = 0; i < bytes; i++) // change unprintable to '.'
if (!isprint(buffer[i]))
buffer[i] = '.';
buffer[i] = '\0'; // terminate string
printf("\t%s\n", buffer); // print out characters
}
return 0;
}
The question I have is quite simple, but I couldn't find a solution so far:
How can I convert a UTF8 encoded string to a latin1 encoded string in C++ without using any extra libs like libiconv?
Every example I could find so far is for latin1 to UTF8 conversion?
typedef unsigned value_type;
template <typename Iterator>
size_t get_length (Iterator p)
{
unsigned char c = static_cast<unsigned char> (*p);
if (c < 0x80) return 1;
else if (!(c & 0x20)) return 2;
else if (!(c & 0x10)) return 3;
else if (!(c & 0x08)) return 4;
else if (!(c & 0x04)) return 5;
else return 6;
}
template <typename Iterator>
value_type get_value (Iterator p)
{
size_t len = get_length (p);
if (len == 1)
return *p;
value_type res = static_cast<unsigned char> (
*p & (0xff >> (len + 1)))
<< ((len - 1) * 6);
for (--len; len; --len)
res |= (static_cast<unsigned char> (*(++p)) - 0x80) << ((len - 1) * 6);
return res;
}
This function will return the unicode code point at p. You can now convert a string using
for (std::string::iterator p = s_utf8.begin(); p != s_utf8.end(); ++p)
{
value_type value = get_value<std::string::iterator&>(p));
if (value > 0xff)
throw "AAAAAH!";
s_latin1.append(static_cast<char>(value));
}
No guarantees, the code is quite old :)
Here is a version of filmor's answer that I wrote for my purposes. A bit more readable, probably a bit slower. I didn't need the template stuff since I was always dealing with char *, and in my case I wanted to replace non-Latin1 character's with _. Just in case it helps someone:
int GetUtf8CharacterLength( unsigned char utf8Char )
{
if ( utf8Char < 0x80 ) return 1;
else if ( ( utf8Char & 0x20 ) == 0 ) return 2;
else if ( ( utf8Char & 0x10 ) == 0 ) return 3;
else if ( ( utf8Char & 0x08 ) == 0 ) return 4;
else if ( ( utf8Char & 0x04 ) == 0 ) return 5;
return 6;
}
char Utf8ToLatin1Character( char *s, int *readIndex )
{
int len = GetUtf8CharacterLength( static_cast<unsigned char>( s[ *readIndex ] ) );
if ( len == 1 )
{
char c = s[ *readIndex ];
(*readIndex)++;
return c;
}
unsigned int v = ( s[ *readIndex ] & ( 0xff >> ( len + 1 ) ) ) << ( ( len - 1 ) * 6 );
(*readIndex)++;
for ( len-- ; len > 0 ; len-- )
{
v |= ( static_cast<unsigned char>( s[ *readIndex ] ) - 0x80 ) << ( ( len - 1 ) * 6 );
(*readIndex)++;
}
return ( v > 0xff ) ? 0 : (char)v;
}
// overwrites s in place
char *Utf8ToLatin1String( char *s )
{
for ( int readIndex = 0, writeIndex = 0 ; ; writeIndex++ )
{
if ( s[ readIndex ] == 0 )
{
s[ writeIndex ] = 0;
break;
}
char c = Utf8ToLatin1Character( s, &readIndex );
if ( c == 0 )
{
c = '_';
}
s[ writeIndex ] = c;
}
return s;
}
Test code:
char s2[ 256 ] = "lif\xc3\xa9 is b\xc3\xa9tt\xc3\xa9r with acc\xc3\xa9nts";
Utf8ToLatin1String( s2 );
latin1 (aka ISO-8859-1) defines the first 256 code points of Unicode. Thus, in UTF-8, if your character is 8 bits, then it will exactly map to the latin1 equivalent. If it's more than 8 bits in length, then there is no correspondent within latin1 and you should map it to some "unknown character" (e.g., \0 or ?).