コード例 #1
0
ファイル: Texture.cpp プロジェクト: eu07/maszyna
void
opengl_texture::load_TGA() {

    std::ifstream file( name + type, std::ios::binary ); file.unsetf( std::ios::skipws );

    // Read the header of the TGA, compare it with the known headers for compressed and uncompressed TGAs
    unsigned char tgaheader[ 18 ];
    file.read( (char *)tgaheader, sizeof( unsigned char ) * 18 );

    while( tgaheader[ 0 ] > 0 ) {
        --tgaheader[ 0 ];

        unsigned char temp;
        file.read( (char *)&temp, sizeof( unsigned char ) );
    }

    data_width = tgaheader[ 13 ] * 256 + tgaheader[ 12 ];
    data_height = tgaheader[ 15 ] * 256 + tgaheader[ 14 ];
    int const bytesperpixel = tgaheader[ 16 ] / 8;

    // check whether width, height an BitsPerPixel are valid
    if( ( data_width <= 0 )
     || ( data_height <= 0 )
     || ( ( bytesperpixel != 1 ) && ( bytesperpixel != 3 ) && ( bytesperpixel != 4 ) ) ) {

        data_state = resource_state::failed;
        return;
    }

    // allocate the data buffer
    int const datasize = data_width * data_height * 4;
	data.resize(datasize);

    // call the appropriate loader-routine
    if( tgaheader[ 2 ] == 2 ) {
        // uncompressed TGA
        if( bytesperpixel == 4 ) {
            // read the data directly
            file.read( reinterpret_cast<char*>( &data[0] ), datasize );
        }
        else {
            // rgb or greyscale image, expand to bgra
            unsigned char buffer[ 4 ] = { 255, 255, 255, 255 }; // alpha channel will be white

            unsigned int *datapointer = (unsigned int*)&data[0];
            unsigned int *bufferpointer = (unsigned int*)&buffer[ 0 ];

            int const pixelcount = data_width * data_height;

            for( int i = 0; i < pixelcount; ++i ) {

                file.read( (char *)&buffer[ 0 ], sizeof( unsigned char ) * bytesperpixel );
                if( bytesperpixel == 1 ) {
                    // expand greyscale data
                    buffer[ 1 ] = buffer[ 0 ];
                    buffer[ 2 ] = buffer[ 0 ];
                }
                // copy all four values in one operation
                ( *datapointer ) = ( *bufferpointer );
                ++datapointer;
            }
        }
    }
    else if( tgaheader[ 2 ] == 10 ) {
        // compressed TGA
        int currentpixel = 0;

        unsigned char buffer[ 4 ] = { 255, 255, 255, 255 };
        const int pixelcount = data_width * data_height;

        unsigned int *datapointer = (unsigned int *)&data[0];
        unsigned int *bufferpointer = (unsigned int *)&buffer[ 0 ];

        do {
            unsigned char chunkheader = 0;

            file.read( (char *)&chunkheader, sizeof( unsigned char ) );

            if( (chunkheader & 0x80 ) == 0 ) {
                // if the high bit is not set, it means it is the number of RAW color packets, plus 1
                for( int i = 0; i <= chunkheader; ++i ) {

                    file.read( (char *)&buffer[ 0 ], bytesperpixel );

                    if( bytesperpixel == 1 ) {
                        // expand greyscale data
                        buffer[ 1 ] = buffer[ 0 ];
                        buffer[ 2 ] = buffer[ 0 ];
                    }
                    // copy all four values in one operation
                    ( *datapointer ) = ( *bufferpointer );

                    ++datapointer;
                    ++currentpixel;
                }
            }
            else {
                // rle chunk, the color supplied afterwards is reapeated header + 1 times (not including the highest bit)
                chunkheader &= ~0x80;
                // read the current color
                file.read( (char *)&buffer[ 0 ], bytesperpixel );

                if( bytesperpixel == 1 ) {
                    // expand greyscale data
                    buffer[ 1 ] = buffer[ 0 ];
                    buffer[ 2 ] = buffer[ 0 ];
                }
                // copy the color into the image data as many times as dictated 
                for( int i = 0; i <= chunkheader; ++i ) {

                    ( *datapointer ) = ( *bufferpointer );
                    ++datapointer;
                    ++currentpixel;
                }
            }

        } while( currentpixel < pixelcount );
    }
    else {
        // unrecognized TGA sub-type
        data_state = resource_state::failed;
        return;
    }

    if( ( tgaheader[ 17 ] & 0x20 ) != 0 ) {
        // normally origin is bottom-left
        // if byte 17 bit 5 is set, it is top-left and needs flip
        flip_vertical();
    }

    downsize( GL_BGRA );
    if( ( data_width > Global.iMaxTextureSize ) || ( data_height > Global.iMaxTextureSize ) ) {
        // for non-square textures there's currently possibility the scaling routine will have to abort
        // before it gets all work done
        data_state = resource_state::failed;
        return;
    }

    // TODO: add horizontal/vertical data flip, based on the descriptor (18th) header byte

    // fill remaining data info
    data_mapcount = 1;
    data_format = GL_BGRA;
    data_components =
        ( bytesperpixel == 4 ?
            GL_RGBA :
            GL_RGB );
    data_state = resource_state::good;

    return;
}
コード例 #2
0
int main(int argc,char *argv[])
{
  //Handles user input, to get file names and command
  if(argc<4 || argc>6)
  {
    printf("Incorrect number of arguments\n");
    printf("Number of arguments: %d\n",argc);
    exit(1);
  }

  const char *input_filename=argv[1];
  printf("Inputfile: %s\n",input_filename);
  const char *output_filename=argv[2];
  printf("Outputfile: %s\n",output_filename);
  char garbage[2];
  int command;
  int radius=3;

  if(1!=sscanf(argv[3],"%d%1s",&command,garbage) || command<0 || command>10)
  {
    printf("Incorrect command\n");
    exit(1);
  }

  if(((command==0) && argc==5 && 1!=sscanf(argv[4],"%d%1s",&radius,garbage)) || radius<1)
  {
    printf("Incorrect radius value\n");
    exit(1);
  }
  
  //Create filters and images
  Filter *filters=initialize_filters(radius);
  Image *input_image=decode(input_filename);
  printf("Width: %d, height: %d\n",input_image->width,input_image->height);
  Image *output_image=generate_output(input_image);

  uint8_t *in_red=input_image->red_channel;
  uint8_t *in_blue=input_image->blue_channel;
  uint8_t *in_green=input_image->green_channel;
  uint8_t *in_alpha=input_image->alpha_channel;
  uint8_t *out_red=output_image->red_channel;
  uint8_t *out_blue=output_image->blue_channel;
  uint8_t *out_green=output_image->green_channel;
  uint8_t *out_alpha=output_image->alpha_channel;
  int height=input_image->height;
  int width=input_image->width;


  //Run chosen command to call functions from functions.c
  switch(command)
  {
    case(0):
    {
      convolve_image(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                    out_alpha,filters[0].filter,filters[0].radius,width,height);
      encode(output_filename,output_image);
      break;
    }
    case(1):
    {
      convolve_image(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                    out_alpha,filters[1].filter,filters[1].radius,width,height);
      encode(output_filename,output_image);
      break;
    }
    case(2):
    {
      convolve_image(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                    out_alpha,filters[2].filter,filters[2].radius,width,height);
      encode(output_filename,output_image);
      break;
    }
    case(3):
    {
      convolve_image(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                    out_alpha,filters[3].filter,filters[3].radius,width,height);
      encode(output_filename,output_image);
      break;
    }
    case(4):
    {
      convolve_image(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                    out_alpha,filters[4].filter,filters[4].radius,width,height);
      encode(output_filename,output_image);
      break;
    }
    case(5):
    {
      convolve_image(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                    out_alpha,filters[5].filter,filters[5].radius,width,height);
      encode(output_filename,output_image);
      break;
    }
    case(6):
    {
      convert_to_gray(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                    out_alpha,gmonomult,width,height);
      encode(output_filename,output_image);
      break;
     }
    case(7):
    {
      flip_vertical(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                  out_alpha,width,height);
      encode(output_filename,output_image);
      break;
    }
    case(8):
    {
      color_threshold(in_red,in_green,in_blue,in_alpha,out_red,out_green,out_blue,
                  out_alpha,width,height,10,150,10);
      encode(output_filename,output_image);
      break;
    }
    default:
      exit(1);
  }

 
  free((double*)filters[0].filter);
  free(filters);
  free_image(input_image);
  free_image(output_image);
  return 0;
}