Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //to compile gcc main.c rs232.c -Wall -O2 -o grab -lSDL
- #include <stdio.h> /* Standard input/output definitions */
- #include <string.h> /* String function definitions */
- #include <unistd.h> /* UNIX standard function definitions */
- #include <fcntl.h> /* File control definitions */
- #include <errno.h> /* Error number definitions */
- #include <termios.h> /* POSIX terminal control definitions */
- #include <stdint.h>
- #include "rs232.h"
- //#define rgb565
- #define rawRGB
- //#define yuv422
- #define preview
- #define timeLapse
- //#define simulate
- //#define simulateWithRand
- //#define simulateWithPattern
- #ifdef preview
- #include <SDL/SDL.h>
- #endif
- #ifdef simulateWithRand
- #include <time.h> /* time */
- #endif
- // ttyACM0
- //qcif 176 × 144
- #define Width_G 640
- #define Height_G 480
- #define CLIP(X) ( (X) > 255 ? 255 : (X) < 0 ? 0 : X)
- // RGB -> YUV
- #define RGB2Y(R, G, B) CLIP(( ( 66 * (R) + 129 * (G) + 25 * (B) + 128) >> 8) + 16)
- #define RGB2U(R, G, B) CLIP(( ( -38 * (R) - 74 * (G) + 112 * (B) + 128) >> 8) + 128)
- #define RGB2V(R, G, B) CLIP(( ( 112 * (R) - 94 * (G) - 18 * (B) + 128) >> 8) + 128)
- // YUV -> RGB
- #define C(Y) ( (Y) - 16 )
- #define D(U) ( (U) - 128 )
- #define E(V) ( (V) - 128 )
- #define YUV2R(Y, U, V) CLIP(( 298 * C(Y) + 409 * E(V) + 128) >> 8)
- #define YUV2G(Y, U, V) CLIP(( 298 * C(Y) - 100 * D(U) - 208 * E(V) + 128) >> 8)
- #define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U) + 128) >> 8)
- // RGB -> YCbCr
- #define CRGB2Y(R, G, B) CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16)
- #define CRGB2Cb(R, G, B) CLIP((36962 * (B - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)
- #define CRGB2Cr(R, G, B) CLIP((46727 * (R - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)
- // YCbCr -> RGB
- #define CYCbCr2R(Y, Cb, Cr) CLIP( Y + ( 91881 * Cr >> 16 ) - 179 )
- #define CYCbCr2G(Y, Cb, Cr) CLIP( Y - (( 22544 * Cb + 46793 * Cr ) >> 16) + 135)
- #define CYCbCr2B(Y, Cb, Cr) CLIP( Y + (116129 * Cb >> 16 ) - 226 )
- struct __attribute__ ((__packed__)) TGAheader
- {
- int8_t idlength;
- int8_t colourmaptype;
- int8_t datatypecode;
- int16_t colourmaporigin;
- int16_t colourmaplength;
- int8_t colourmapdepth;
- int16_t x_origin;
- int16_t y_origin;
- int16_t width;
- int16_t height;
- int8_t bitsperpixel;
- int8_t imagedescriptor;
- // pixel data follows header
- };
- struct TGAheader tgahead;
- // How many frames time values to keep
- // The higher the value the smoother the result is...
- // Don't make it 0 or less :)
- char port=24;
- #ifdef preview
- #define FRAME_VALUES 10
- // An array to store frame times:
- uint32_t frametimes[FRAME_VALUES];
- // Last calculated SDL_GetTicks
- uint32_t frametimelast;
- // total frames rendered
- uint32_t framecount;
- // the value you want
- float framespersecond;
- // This function gets called once on startup.
- void fpsinit() {
- // Set all frame times to 0ms.
- memset(frametimes, 0, sizeof(frametimes));
- framecount = 0;
- framespersecond = 0;
- frametimelast = SDL_GetTicks();
- }
- void fpsthink() {
- uint32_t frametimesindex;
- uint32_t getticks;
- uint32_t count;
- uint32_t i;
- // frametimesindex is the position in the array. It ranges from 0 to FRAME_VALUES.
- // This value rotates back to 0 after it hits FRAME_VALUES.
- frametimesindex = framecount % FRAME_VALUES;
- // store the current time
- getticks = SDL_GetTicks();
- // save the frame time value
- frametimes[frametimesindex] = getticks - frametimelast;
- // save the last frame time for the next fpsthink
- frametimelast = getticks;
- // increment the frame count
- framecount++;
- // Work out the current framerate
- // The code below could be moved into another function if you don't need the value every frame.
- // I've included a test to see if the whole array has been written to or not. This will stop
- // strange values on the first few (FRAME_VALUES) frames.
- if (framecount < FRAME_VALUES) {
- count = framecount;
- } else {
- count = FRAME_VALUES;
- }
- // add up all the values and divide to get the average frame time.
- framespersecond = 0;
- for (i = 0; i < count; i++) {
- framespersecond += frametimes[i];
- }
- framespersecond /= count;
- // now to make it an actual frames per second value...
- framespersecond = 1000.f / framespersecond;
- }
- #endif
- /*int open_port(void)
- {
- int fd; // File descriptor for the port
- fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
- if (fd == -1)
- {
- /*
- * Could not open the port.
- */
- /* puts("open_port: Unable to open /dev/ttyACM0");
- }
- else
- {
- struct termios options;
- //fcntl(fd, F_SETFL, 0);
- fcntl(fd, F_SETFL, FNDELAY);
- /*
- * Get the current options for the port...
- */
- // tcgetattr(fd, &options);
- /*
- * Set the baud rates to 2M
- */
- /* cfsetispeed(&options, B2000000);
- cfsetospeed(&options, B2000000);
- printf("2000000 = %d",B2000000);
- /*
- * Enable the receiver and set local mode...
- */
- /*options.c_cflag |= (CLOCAL | CREAD);
- options.c_cflag &= ~CSIZE; // Mask the int8_tacter size bits
- options.c_cflag |= CS8; // Select 8 data bits
- //no parity bit
- options.c_cflag &= ~PARENB;
- options.c_cflag &= ~CSTOPB;
- options.c_cflag &= ~CSIZE;
- options.c_cflag |= CS8;
- options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//raw mode
- /*
- * Set the new options for the port...
- */
- /*
- tcsetattr(fd, TCSANOW, &options);
- }
- return (fd);
- }*/
- #ifdef preview
- void saveSurface(uint8_t * pixDat)
- {
- FILE * myfile=fopen("capture.tga","wb");
- fwrite(&tgahead,1,sizeof(tgahead),myfile);
- #ifdef rgb565
- fwrite(pixDat,2,Width_G*Height_G,myfile);
- #else
- fwrite(pixDat,3,Width_G*Height_G,myfile);
- #endif
- fclose(myfile);
- }
- #endif
- inline double clampD(double val)
- {
- if (val < 0.0)
- {
- //printf("Clamped at %f\n",val);
- val=0.0;
- }
- if (val > 255.0)
- {
- //printf("Clamped at %f\n",val);
- val=255.0;
- }
- }
- #ifdef timeLapse
- int getkey() {
- int character;
- struct termios orig_term_attr;
- struct termios new_term_attr;
- /* set the terminal to raw mode */
- tcgetattr(fileno(stdin), &orig_term_attr);
- memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
- new_term_attr.c_lflag &= ~(ECHO|ICANON);
- new_term_attr.c_cc[VTIME] = 0;
- new_term_attr.c_cc[VMIN] = 0;
- tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);
- /* read a character from the stdin stream without blocking */
- /* returns EOF (-1) if no character is available */
- character = fgetc(stdin);
- /* restore the original terminal attributes */
- tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
- return character;
- }
- #endif
- void waitImg(void)
- {
- //puts("Waiting for 'IMG ' command to start transfer");
- static const char Sig[]="RDY";
- uint8_t tempC,x;
- uint32_t junkC=0;
- //puts("Waiting for RDY command");
- for (x=0;x<3;x++)
- {
- do {
- RS232_PollComport(port,&tempC,1);
- if (tempC != Sig[x])
- {
- junkC++;
- printf("Junk Char %d or %c while waiting for %c so far skiped %d\n",tempC,tempC,Sig[x],junkC);
- }
- } while (tempC != Sig[x]);
- }
- if (junkC != 0)
- printf("%d junk bytes skipped\n",junkC);
- //puts("Waiting for response");
- //RS232_SendByte(port,'R');
- //if (junkC == 3)
- // RS232_PollComport(port,&tempC,1);//skip 1 byte
- //puts(" ");
- //puts("Ok to get data now");
- }
- int main()
- {
- tgahead.idlength=0;
- tgahead.colourmaptype=0;
- tgahead.datatypecode=2;
- tgahead.colourmaporigin=0;
- tgahead.colourmaplength=0;
- tgahead.colourmapdepth=16;
- tgahead.x_origin=0;
- tgahead.y_origin=0;
- tgahead.width=Width_G;
- tgahead.height=Height_G;
- #ifdef rgb565
- tgahead.bitsperpixel=16;
- #else
- tgahead.bitsperpixel=24;
- #endif
- tgahead.imagedescriptor=0;
- if (sizeof(tgahead) != 18)
- {
- printf("Size of TGA header is %d\n",sizeof(tgahead));
- return 1;
- }
- #ifdef simulateWithRand
- /* initialize random seed: */
- srand (time(NULL));
- #endif
- #ifdef preview
- //initate sdl
- uint16_t skipB=0;
- SDL_Surface* screen = NULL;
- #ifdef rgb565
- SDL_Surface* image = SDL_CreateRGBSurface(SDL_SWSURFACE,Width_G,Height_G,16,be16toh(0xF800),be16toh(0x07e0),be16toh(0x1F),0);
- #else
- SDL_Surface* image = SDL_CreateRGBSurface(SDL_SWSURFACE,Width_G,Height_G,24,0x0000ff,0x00ff00,0xff0000,0);
- #endif
- printf("Image Pitch %d\n",image->pitch);
- //Start SDL
- SDL_Init(SDL_INIT_EVERYTHING);
- //Set up screen
- screen = SDL_SetVideoMode(Width_G,Height_G, 32, SDL_SWSURFACE );
- SDL_Event event;
- uint8_t saveImg=0;
- #endif
- //int fd=open_port();
- tryagain:
- if(RS232_OpenComport(port, 500000))
- {
- printf("Can not open comport %d\n",port);
- /*if (port == 25)
- return(0);
- else
- port++;*/
- goto killPGM;
- }
- //imageRaw = malloc(176*2304*2);
- #ifndef preview
- FILE * myfile=fopen("out.tga","wb");
- fwrite(&tgahead,1,sizeof(tgahead),myfile);
- #endif
- #ifndef rgb565
- uint8_t yuvDat[4];
- #endif
- int bytes;
- #ifdef rawRGB
- uint8_t rawP;
- #endif
- #ifdef simulate
- uint16_t pix=0;
- uint8_t buff=0;
- #endif
- #ifdef preview
- int exitLoop=1;
- fpsinit();
- //skipB=128;
- while (exitLoop)
- {
- SDL_LockSurface(image);
- uint8_t * imgPtr=image->pixels;
- //puts("Grabbing image");
- #endif
- uint16_t x,y;
- x=0;
- y=0;
- #ifdef simulate
- #ifndef simulateWithRand
- #ifndef simulateWithPattern
- pix++;
- printf("Pixel Value: %d\n",pix);
- #endif
- #endif
- #endif
- #ifdef simulateWithPattern
- pix=0;
- #endif
- //skipB=1;
- #ifdef rgb565
- bytes=((Width_G*Height_G)*2);
- #else
- bytes=0;
- #endif
- #ifndef simulate
- waitImg();
- #endif
- while (1)
- {
- #ifdef simulate
- int n=1;
- /*if (x&1)
- buff=pix>>8;
- else
- {
- #ifdef simulateWithRand
- pix=rand();
- #endif
- buff=pix&255;
- }*/
- #ifdef simulateWithPattern
- #ifdef rgb565
- pix++;
- #elif defined yuv422
- yuvDat[0]=buff++;
- yuvDat[1]=buff++;
- yuvDat[2]=buff++;
- yuvDat[3]=buff++;
- #else
- rawP=buff++;
- #endif
- #endif
- #else
- #ifdef rawRGB
- int n =RS232_PollComport(port,&rawP,1);
- #elif defined rgb565
- int n = RS232_PollComport(port,imgPtr,128);
- #else
- int n = RS232_PollComport(port,yuvDat,4);
- if (n < 4)
- printf("Read %d bytes instead of 4\n",n);
- #endif
- //printf("X: %d Y: %d \r",x,y);
- #endif
- if (n ==0)
- {
- //usleep(100);
- puts("0 bytes read");
- continue;
- }
- #ifndef preview
- fputc(buff, myfile);
- #endif
- #ifdef preview
- if (skipB==0)
- {
- #ifdef rgb565
- imgPtr+=128;
- x+=128;
- #elif defined rawRGB
- //see what color this pixel should set to
- /*R G
- G B*/
- if (y&1)
- {//odd
- if (x&1)//if odd
- imgPtr[2]=rawP;//blue
- else
- imgPtr[1]=rawP;//green
- }
- else
- {//even
- if (x&1)//if odd pixel
- imgPtr[1]=rawP;//green
- else
- *imgPtr=rawP;//red
- }
- imgPtr+=3;//next pixel
- x++;
- #else
- //yuvDat=(uint8_t *)&buff;
- x+=4;
- #endif
- #ifdef yuv422
- if (((x & 3)==0) && (x != 0))
- {//convert pixels
- /*
- Y = pixel0;
- U = pixel1;
- Y1 = pixel2;
- V = pixel3;
- */
- /* *imgPtr++=yuvDat[0] + 1.4075 * (yuvDat[3] - 128.0);//red
- *imgPtr++=yuvDat[0] - 0.3455 * (yuvDat[1] - 128) - (0.7169 * (yuvDat[3] - 128));//green
- *imgPtr++=yuvDat[0] + 1.7790 * (yuvDat[1] - 128);//blue
- *imgPtr++=yuvDat[2] + 1.4075 * (yuvDat[3] - 128);//red
- *imgPtr++=yuvDat[2] - 0.3455 * (yuvDat[1] - 128) - (0.7169 * (yuvDat[3] - 128));//green
- *imgPtr++=yuvDat[2] + 1.7790 * (yuvDat[1] - 128);//blue */
- *imgPtr++=YUV2R(yuvDat[0],yuvDat[1],yuvDat[3]);
- *imgPtr++=YUV2G(yuvDat[0],yuvDat[1],yuvDat[3]);
- *imgPtr++=YUV2B(yuvDat[0],yuvDat[1],yuvDat[3]);
- *imgPtr++=YUV2R(yuvDat[2],yuvDat[1],yuvDat[3]);
- *imgPtr++=YUV2G(yuvDat[2],yuvDat[1],yuvDat[3]);
- *imgPtr++=YUV2B(yuvDat[2],yuvDat[1],yuvDat[3]);
- }
- #endif
- #ifdef rawRGB
- if (x==Width_G)
- #else
- if (x==Width_G*2)//size is same for both yuv422 and rgb565
- #endif
- {
- //if (y==0)
- // skipB=1;
- //if (y/96*96 == y)
- // skipB=1;
- #ifdef rawRGB
- if (y&1)
- {
- //do bayer interopulation
- imgPtr-=Width_G*6;//go back 2 rows
- uint16_t wx;
- for (wx=0;wx<Width_G;wx+=2)
- {
- //this will do a 2x2 pixel rectangle
- /*R G
- G B*/
- imgPtr[1+wx*3]=imgPtr[4+wx*3];//green
- imgPtr[2+wx*3]=imgPtr[((Width_G+wx)*3)+5];//blue
- imgPtr[3+wx*3]=imgPtr[wx*3];//red
- imgPtr[5+wx*3]=imgPtr[((Width_G+wx)*3)+5];//blue
- imgPtr[((Width_G+wx)*3)]=imgPtr[wx*3];//red
- imgPtr[((Width_G+wx)*3)+2]=imgPtr[((Width_G+wx)*3)+5];//blue
- imgPtr[((Width_G+wx)*3)+3]=imgPtr[wx*3];//red
- imgPtr[((Width_G+wx)*3)+4]=imgPtr[((Width_G+wx)*3)+1];//green
- }
- //imgPtr+=Width_G*6;//go back to the origional posistion
- SDL_UnlockSurface(image);
- SDL_BlitSurface(image, NULL, screen, NULL );
- SDL_Flip(screen);
- SDL_LockSurface(image);
- imgPtr=image->pixels+(y*image->pitch);
- }
- #endif
- while( SDL_PollEvent( &event ) )
- {
- if( event.type == SDL_QUIT )
- {
- //Quit the program
- exitLoop=0;
- goto quit;
- }
- if (event.type == SDL_KEYDOWN)
- {
- if (event.key.keysym.sym == SDLK_s)
- {
- puts("Saving Image");
- saveImg=1;
- }
- else if (event.key.keysym.sym == SDLK_l)
- {
- puts("Going back a line");
- y--;
- }
- else if (event.key.keysym.sym == SDLK_p)
- {
- puts("skipping 31 reads");
- skipB=31;
- }
- else
- {
- puts("skipping read");
- skipB=1;
- }
- }
- }
- y++;
- //if (((y/96)*96) == y)
- //{
- //printf("y = %d\n",y);
- #ifndef simulate
- if (y!=Height_G)
- {
- waitImg();
- imgPtr=image->pixels+(y*image->pitch);
- }
- #endif
- //}
- //if (y!=Height_G)
- //{
- #ifndef rawRGB
- if ((y&31) == 0)
- {
- SDL_UnlockSurface(image);
- SDL_BlitSurface(image, NULL, screen, NULL );
- SDL_Flip(screen);
- SDL_LockSurface(image);
- imgPtr=image->pixels+(y*image->pitch);
- }
- #endif
- //}
- x=0;
- }
- }
- else
- {
- skipB--;
- puts("Byte Skipped");
- }
- #endif
- #ifdef rgb565
- bytes-=128;
- #elif defined yuv422
- bytes+=4;
- #else
- bytes++;
- #endif
- //printf("Grabing image on byte %d y: %d\r",bytes,y); makes program run slower
- #ifdef rgb565
- if (bytes <= 0)
- #else
- if (y==Height_G)//if (bytes == ((Width_G*Height_G)*2))
- #endif
- {//same for both rgb565 and yuv422
- #ifdef preview
- if (saveImg != 0)
- {
- saveImg=0;
- SDL_LockSurface(image);
- saveSurface(image->pixels);
- SDL_UnlockSurface(image);
- SDL_SaveBMP(image,"OUT.bmp");
- }
- #ifdef timeLapse
- else
- {//time lapse
- static int count=0;
- count++;
- static char buf[1024];
- sprintf(buf,"frame %d",count);
- SDL_SaveBMP(image,buf);
- }
- #endif
- #endif
- break;
- }
- //usleep(100);
- }//end of loop
- quit:
- #ifdef preview
- SDL_UnlockSurface(image);
- SDL_BlitSurface(image, NULL, screen, NULL );
- SDL_Flip(screen);
- fpsthink();
- printf("Frames Per Second %f\n", framespersecond);
- }
- #ifndef simulate
- puts("Serial Port Closed");
- RS232_CloseComport(port);
- #endif
- killPGM:
- SDL_FreeSurface(image);
- //Quit SDL
- SDL_Quit();
- #endif
- #ifndef preview
- fclose(myfile);
- #endif
- puts("");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment