?
Solved

Error: "Invalid direction"

Posted on 2007-10-09
20
Medium Priority
?
371 Views
Last Modified: 2010-04-15
Experts,

the for loop below throws error "invalid direction".   How do I fix it?

*********************
int newim;
for (i = 0; i < totalPixels; i++){
      newim[i] = tl[image[i]];
};
*********************

EEH
0
Comment
Question by:ExpExchHelp
  • 8
  • 6
  • 4
  • +2
20 Comments
 
LVL 20

Expert Comment

by:REA_ANDREW
ID: 20040219
int newim;
for (i = 0; i < totalPixels; i++){
      newim[i] = tl[image[i]];
};

you seem to have declared newim as an int and not an Array for a start.  Are you aware of this?

Andrew
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 20040234
Hi ExpExchHelp,

'int newdim;' declares 'newdim' as a single int, 'newdim[i]' tries to treat 'newdim' as an array of ints.

You need to instantiate 'newdim' as an array of ints of sizeof 'totalPixels'.

Hope that helps,

ZOPPO
0
 

Author Comment

by:ExpExchHelp
ID: 20040253
I'm just learning C/C++.  How do I do this?  

EEH
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 31

Accepted Solution

by:
Zoppo earned 600 total points
ID: 20040263
Hi,

if 'totalPixels' is a constant value you can simly do

int newdim[ totalPixels ];

otherwise you need to dynamically instantiate it somehow like this:

int *newdim = new int [ totalPixels ];

... // do your code here

delete [] newdim; // this is needed to release the used memory afterwards


ZOPPO
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20040267
>>>> How do I do this?  

  int newim[1000];   // an array of int, size 1000

Regards, Alex
0
 

Author Comment

by:ExpExchHelp
ID: 20040272
I'll give it a try...
0
 

Author Comment

by:ExpExchHelp
ID: 20040293
Zoppo... I'm afraid I impact other functions.    

itsmeandnobodyelse... adding the "[1000]" prevents the error form occuring.   What exactly does it do?

EEH
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20040306
>>>> tl[image[i]];

How is the 'tl' and the 'image' defined?

Generally,  tl[image[i]]; is a dangerous statement cause it requires that

          image[i] < sizeof(tl)/sizeof(int)   // == size of the array tl

for all i and that

          image[i] >= 0

If you didn't know how to define an array, the statement is even more dangerous for you.

Regards, Alex
0
 

Author Comment

by:ExpExchHelp
ID: 20040319
itsmeandnobodyelse,

well... it compiles and builds properly.   But now when executing, an error dialog box pops up indicating that "Equalization.exe has encountered a problem".

Essentially, the program "blows up" on me.

EEH
0
 

Author Comment

by:ExpExchHelp
ID: 20040341
Below is the entire code... what's missing?

BTW, I now raised the points to 500.

EEH

**********************************************************************************
// Standard libraries
#include <stdio.h> /* This header file defines the I/O functions */
#include <stdlib.h> /* include standard dfeinitions like exit() */
#include <math.h> /* this includes math functions*/

// These #define statements allow to convert numerical values into string
// values.
#define FALSE 0
#define TRUE 1

// The main function has always access to the programs.
// argc = counter; argv = array of strings
int main(int argc, char **argv){

    // Initialize variables
      FILE *fpIn;
      FILE *fpOut;
      FILE *fresults;
      char *string;
      char c;
      int i;
      int j;
      int k;
      int l;
      int cnt1[256];
      int cnt2[256];
      int highVal;
      int doneReading = FALSE;
      int numberOfRows, numberOfColumns, numberOfBands;
      int totalPixels;
      int maximum=-1;
      int meanI;
      int mode;
      float scalefactor;

      // Declares a pointer of this type.  The data will be stored in
      // "*image".
      unsigned char *image;

      // Defines a 2-dimensional array
         unsigned char histogram[256][256];


         // The read program is invoked by: readimage inputfile outputfile.
      // Program requires at least 3 arguments:
      // 1. "call program"
      // 2. "input pgm"
      // 3. "output pgm"; the histogram will be written to this outfile file
      if (argc < 3) {
            fprintf(stderr,"Usage: readimage input-file-name output-file-name\n");
            exit(0);
      }
      fpIn = fopen(argv[1],"rb");   // argv[1] contains the filename
      if (fpIn == NULL) {
            fprintf(stderr,"%s either cannot be read or does not exist\n", argv[1]);
            exit(-1);
      }
      string = (char *) calloc(256,1);  // initialized dynamic memory allocation
      while (!doneReading && (c = (char) fgetc(fpIn)) != '\0')
            switch(c) {
        case 'P':
              c = (char) getc(fpIn);
              switch(c) {
        case '2':
              numberOfBands = 1;
              /* ppmType = PPMASCII; */
              break;
        case '3':
              numberOfBands = 3;
              /* ppmType = PPMASCII; */
              break;
        case '5':
              numberOfBands = 1;
              /* ppmType = PPMGRAY; */
              break;
        case '6':
              numberOfBands = 3;
              /* ppmType = PPMRAW; */
              break;
              }
              c = (char) getc(fpIn);
              if (c != 0x0A) {
                    ungetc(c,fpIn);
              }
              else {
                    ungetc(c,fpIn);
                    fgets(string,256,fpIn);
              }
              break;
        case '#':
              fgets(string,256,fpIn);
              break;
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
              ungetc(c,fpIn);
              fscanf(fpIn,"%d %d %d", &numberOfColumns, &numberOfRows, &highVal);
              doneReading = TRUE;
              fgetc(fpIn);
              break;
      }

      // De-allocate memory
      free(string);

      // Allocate this many number of bytes to the image.
      totalPixels = numberOfRows*numberOfColumns*numberOfBands;

      // Reads from the specified pointer; 1 byte, # of pixels, and file pointer
      image = (unsigned char *) malloc(totalPixels);
      l = fread(image,1,totalPixels,fpIn);
      fprintf(stderr,"fread returned %d bytes\n", l);


      // Generate histogram from input file to produce histogram
      for (i = 0; i < 256; i++) {
        cnt1[i] = 0;
      }

      for (i=0; i < totalPixels; i++) {
        l = image[i];
            (cnt1[l])++;
      }

      for(i=0;i<256;i++) {
                  fprintf(stderr,"cnt1[%d] = %d\n", i, cnt1[i]);
        }

       // Determine maximum g value (including the MODE)
      mode = 0;
      for (i=0;i<256;i++) {
            if(cnt1[i]>maximum) {
                  maximum=cnt1[i];
         mode = i;
            }
      }

      // Resizes the graphic to fit to an optimal scale
      scalefactor=256.0/maximum;

      for(i=0;i<256;i++) {
      cnt2[i]=scalefactor*cnt1[i];
      }

      // Inverts the graphic from top down to bottom up by decrementing from 255.
      // Then set data to maximum brightness of 255.
      for (i = 0; i < 256; i++) {
            for (j = 0; j < 256; j++) {
      histogram[i][j] = 0;
            }
      }

      for(i=0;i<256;i++) {
            for (j=255;j>255-cnt2[i];j--) {
                        histogram[j][i]=256;
            }
      }

//First, get a denominator used to get probability

int denominator=0;

for(int cntr=0; cntr < 256; cntr++)
{
        denominator += cnt2[cntr];
}

//Now that the denominator is found, store the values from cnt2 into cnt3
//adjusted by dividing by the denominator.

float cnt3[256]; float numval = 0;
float numval2 = 0;


//Note that numval2 is used to convert the int value to a float value
//numval is then used to store the values of numval2 divided by the denominator,
//which is the probability
//this array of probabilities is called cnt3

for(int cntr=0; cntr <256; cntr++)
{
        numval2 = cnt2[cntr];
        numval = (numval2 / denominator);
        cnt3[cntr] = numval;

}

//print the new probability table
for(int i=0; i<256;i++)
{
       fprintf(stdout,"\nCNT2 element %d", i);
       fprintf(stdout," = %f", cnt3[i]);

}

//*****This is the autolevel calculations

//now find the clo and chi values by summing from the top and
//bottom of the table.  the location of clo and chi are stored in the
//int clo chi integers, and the values stored there (i.e. ~0.005) are stored in
//double clo_val and chi_val
int clo=0; float clo_val=0;int chi=0;float chi_val=0;
for(int i=0; i<256; i++)
{
    clo_val += cnt3[i];
    if(clo_val >= 0.005)
        {clo = i; break;}
}

for(int i=255; i>-1; i--)
{
    chi_val += cnt3[i];
    if(chi_val >= 0.005)
        {chi = i; break;}
}


//now do the crunching to find the values for the TL data table
int tl[256]; float trash = 0;int num = 0; int den = 0;
float fnum = 0; float fden = 0;

for(int i=0;i<256;i++)
{
    num = (i-clo);
    fnum = num;
    den = (chi-clo);
    fden = den;
    trash = fnum/fden;
    trash *= 255;
    if(trash <= 0){tl[i] = 0;}
    else if(trash >=255){tl[i] = 255;}
    else{tl[i] = trash;}
}

//***This is now the beginning of the histogram equalization

//now we want to get an array of the CDF values, with 255 containing the sum
//which should be 1.  CNT3 contains the probability values, so a new array CNT4
//will be created which contains the sums of the CNT3 values.  Note that the
//dummy variable used for calculations is named "trash2" because the variable
//"trash" was already previously used for other calculations

float cnt4[256]; float trash2 = cnt3[0];
cnt4[0] = trash2;
for(int i =1; i<256;i++)
{
    trash2 = cnt3[i];
    trash2 += cnt4[i-1];
    cnt4[i] = trash2;
}
//now that the CDF array has been obtained, the values for each array
//element must be multiplied by 255 and converted to an integer value
//this will be done by storing the float value from CNT4 to an int array CNT5

int cnt5[256];

for(int i = 0; i<256;i++)
{
    trash2 = cnt4[i];
    trash2 *= 255;
    cnt5[i] = trash2;
}

//now print the CNT5 array to ensure correctness
fprintf(stdout,"\n");
for(int i=0; i<256;i++)
{
       fprintf(stdout,"\nCNT5 element %d", i);
       fprintf(stdout," = %d", cnt5[i]);
}
   


      // Inverts the graphic from top down to bottom up by decrementing from 255.
      // Then sets data to maximum brightness of 255.
      for (i = 0; i < 256; i++) {
            for (j = 0; j < 256; j++) {
                  histogram[i][j] = 0;
            }
      }

      for(i=0;i<256;i++) {
            for (j=255;j>255-cnt2[i];j--) {
                  histogram[j][i]=255;
            }
      }




//************** error occurs below **************


int newim[1000];


for (i = 0; i < totalPixels; i++){
      newim[i] = tl[image[i]];
};

//**********************************************











      // Generate the histogram
      fpOut = fopen(argv[2],"wb");

   // Write image header
      fprintf(fpOut,"P5\n256 256\n255\n");
   for(i=0;i<256;i++){
      fwrite(histogram[i],256,1,fpOut);
      }

      // Generate "Validation.txt"
      fresults = fopen("Validation.txt", "w");
      if (fresults==NULL)    {
         printf("Routine cannot open 'Validation.txt' for output.\n");
         exit(1);
   }

      for(i=0;i<256;i++){
            fprintf(fresults,"%d,%d\n", i, cnt5[i]);
      }

   // Close txt file
      fclose(fresults);


exit(0);
}
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 1200 total points
ID: 20040357
>>>> What exactly does it do?

   int newim[1000];

defines a variable 'newim' which allocates a storage of 1000 integers in memory.

newim[0]  is the first of these 'array elements' while newim[999] is the last one.

You can do,

    int newim[1000] = { 0 };   // inits all 1000 integers with 0
    int i = 100;            
    newim[i] = 12345;   // assign a constant integer to the 101th array element.


Your loop  

  int newim[1000] = { 0 };   // inits all 1000 integers with 0
  for (i = 0; i < totalPixels; i++)
  {
      newim[i] = tl[image[i]];
  };

would assign the elements 0 ..... totalPixel-1 of 'newim' with values evaluated from two other arrays 'tl' and 'image'.

Regards, Alex

0
 
LVL 31

Assisted Solution

by:Zoppo
Zoppo earned 600 total points
ID: 20040373
Hi,

IMO the error occurs since 1000 < totalPixels

you can initiate newdim where you do it with image, i.e.:

Y ...
> totalPixels = numberOfRows*numberOfColumns*numberOfBands;
>
>     // Reads from the specified pointer; 1 byte, # of pixels, and file pointer
>      image = (unsigned char *) malloc(totalPixels);
>
>      int* newdim = (int*)malloc( totalPixels );
> ...
> // when you don't need newdim anymore you need to release it's memory
> free( newdim );


ZOPPO
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 1200 total points
ID: 20040438
>>>> "Equalization.exe has encountered a problem".
I assume 1000 is too less. You need to choose a value which is at least  numberOfRows*numberOfColumns*numberOfBands == totalPixel.

As 'totalPixel' is not a constant you can't us it for the dimension of a fixed-size array. Hence you should make a dynamically sized array:

    int * newim = (int*)malloc(totalPixel * sizeof(int));  

Note in C/C++ a pointer pointing to the first array element can be used like an array with one exception: the sizeof function would return pointer size and not array size. Another thing is that a pointer (dynamically sized array) needs to be freed after use:

  free(newim);

But do not access the variable after freeing the storage.

Regards, Alex
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20040445
Sorry Zoppo, I didn't refresh in the meantime.
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 20040471
No problem - in fact your comment is more correct I guess since I forgot the '... * sizof( int)' in the malloc statement ...
0
 

Author Comment

by:ExpExchHelp
ID: 20040495
I gotta run for right now... I'll check tonight again.

Thanks so much for your help already!!!

Later,
EEH
0
 

Author Comment

by:ExpExchHelp
ID: 20040501
forgot to increase points...
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 1200 total points
ID: 20040664
EEH,

I assume you got that code from somewhere. I compiled it at my system and got 11 warnings because the code converts double to float, float to int, int to float, char to int and int to char without cast, i. e. there is possible loss of data as these types have different ranges.

>>>> histogram[j][i]=256;    [warning: int to char conversion.]
Note, histogram[j][i] == 0 after that statement cause a char contains only numbers 0 ... 255 (or -128 ... 127).

Assigning 256 gives an overflow and the result is 0.

Regards, Alex
0
 
LVL 16

Assisted Solution

by:PaulCaswell
PaulCaswell earned 200 total points
ID: 20050865
As a general rule, if your program just goes bang 'somewhere' try sprinkling:

printf("I got to line %d\n", __LINE__);

all over the place. This way you can narrow down your search to where the problem is by what's been printed when it dies.

Note: __LINE__ is a microsoft define for the current line in the original source file. There is usually an equivalent in most implementations.

Paul
0
 

Author Comment

by:ExpExchHelp
ID: 20071089
Excellent... I finally got it to work.

I appreciate everyone's help in this matter.  

EEH
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

755 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question