int run_blur(int c, char* src, char* dst){ BMP* bmp = bmp_read(src); if(bmp==0) { return -1;} // open error uint8_t* data = bmp_get_data(bmp); uint32_t h = *(bmp_get_h(bmp)); uint32_t w = *(bmp_get_w(bmp)); if(w%4!=0) { return -1;} // do not support padding uint8_t* dataC = 0; if(*(bmp_get_bitcount(bmp)) == 24) { dataC = malloc(sizeof(uint8_t)*4*h*w); to32(w,h,data,dataC); } else { dataC = data; } if(c==0) C_blur(w,h,dataC); else if(c==1) ASM_blur1(w,h,dataC); else if(c==2) ASM_blur2(w,h,dataC); else {return -1;} if(*(bmp_get_bitcount(bmp)) == 24) { to24(w,h,dataC,data); free(dataC); } bmp_save(dst,bmp); bmp_delete(bmp); return 0; }
int run_hsl(int c, char* src, char* dst, float hh, float ss, float ll) { BMP* bmp = bmp_read(src); if(bmp==0) { return -1;} // open error if(ss>1) ss=1; else if(ss<-1) ss=-1; if(ll>1) ll=1; else if(ll<-1) ll=-1; uint8_t* data = bmp_get_data(bmp); uint32_t h = *(bmp_get_h(bmp)); uint32_t w = *(bmp_get_w(bmp)); if(w%4!=0) { return -1;} // do not support padding uint8_t* dataC = 0; if(*(bmp_get_bitcount(bmp)) == 24) { dataC = malloc(sizeof(uint8_t)*4*h*w); to32(w,h,data,dataC); } else { dataC = data; } if(c==0) C_hsl(w,h,dataC,hh,ss,ll); else if(c==1) ASM_hsl1(w,h,dataC,hh,ss,ll); else if(c==2) ASM_hsl2(w,h,dataC,hh,ss,ll); else {return -1;} if(*(bmp_get_bitcount(bmp)) == 24) { to24(w,h,dataC,data); free(dataC); } bmp_save(dst,bmp); bmp_delete(bmp); return 0; }
int run_merge(int c, char* src1, char* src2, char* dst, float value){ if(dst==0) { return -1;} // non destine if(value>1) value=1; else if(value<0) value=0; BMP* bmp1 = bmp_read(src1); BMP* bmp2 = bmp_read(src2); if(bmp1==0 || bmp2==0) { return -1;} // open error uint8_t* data1 = bmp_get_data(bmp1); uint8_t* data2 = bmp_get_data(bmp2); uint32_t h1 = *(bmp_get_h(bmp1)); uint32_t w1 = *(bmp_get_w(bmp1)); uint32_t h2 = *(bmp_get_h(bmp2)); uint32_t w2 = *(bmp_get_w(bmp2)); if(w1%4!=0 || w2%4!=0) { return -1;} // do not support padding if( w1!=w2 || h1!=h2 ) { return -1;} // different image size uint8_t* data1C = 0; uint8_t* data2C = 0; if(*(bmp_get_bitcount(bmp1)) == 24) { data1C = malloc(sizeof(uint8_t)*4*h1*w1); data2C = malloc(sizeof(uint8_t)*4*h2*w2); to32(w1,h1,data1,data1C); to32(w2,h2,data2,data2C); } else { data1C = data1; data2C = data2; } if(c==0) C_merge(w1,h1,data1C,data2C,value); else if(c==1) ASM_merge1(w1,h1,data1C,data2C,value); else if(c==2) ASM_merge2(w1,h1,data1C,data2C,value); else {return -1;} if(*(bmp_get_bitcount(bmp1)) == 24) { to24(w1,h1,data1C,data1); free(data1C); free(data2C); } bmp_save(dst,bmp1); bmp_delete(bmp1); bmp_delete(bmp2); return 0; }
int run_hsl(int c, char* src, char* dst, float hh, float ss, float ll, int times) { BMP* bmp = bmp_read(src); if(bmp==0) { return -1;} // open error if(ss>1) ss=1; else if(ss<-1) ss=-1; if(ll>1) ll=1; else if(ll<-1) ll=-1; uint8_t* data = bmp_get_data(bmp); uint32_t h = *(bmp_get_h(bmp)); uint32_t w = *(bmp_get_w(bmp)); if(w%4!=0) { return -1;} // do not support padding uint8_t* dataC = 0; if(*(bmp_get_bitcount(bmp)) == 24) { dataC = malloc(sizeof(uint8_t)*4*h*w); to32(w,h,data,dataC); } else { dataC = data; } unsigned long start, end; switch(c){ case 0: RDTSC_START(start); C_hsl(w,h,dataC,hh,ss,ll); RDTSC_STOP(end); break; case 1: RDTSC_START(start); ASM_hsl1(w,h,dataC,hh,ss,ll); RDTSC_STOP(end); break; case 2: RDTSC_START(start); ASM_hsl2(w,h,dataC,hh,ss,ll); RDTSC_STOP(end); break; default: return -1; break; } unsigned long delta = end - start; printf("%lu", delta); if(*(bmp_get_bitcount(bmp)) == 24) { to24(w,h,dataC,data); free(dataC); } bmp_delete(bmp); return 0; }
int main(int argc, char* argv[]){ if (argc != 2) { print_help(argv[0]); return 0; } char* fileName = argv[1]; BMP* bmp = bmp_read(fileName); if (bmp == 0) { printf("Invalid filename.\n"); return 0; } uint8_t *data = bmp_get_data(bmp); int h = (int) *bmp_get_h(bmp); int w = (int) *bmp_get_w(bmp); int c1 = ((BMPIH*)(bmp->ih))->biBitCount; if(c1 == 32) { for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int pos = (i*w+j)*4; uint8_t r = data[pos+3]; uint8_t g = data[pos+2]; uint8_t b = data[pos+1]; uint8_t a = data[pos+0]; printf("[%u,%u,%u,%u]\n", (int) r, (int) g, (int) b, (int) a); } } } if(c1 == 24) { for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int pos = (i*w+j)*3; uint8_t r = data[pos+2]; uint8_t g = data[pos+1]; uint8_t b = data[pos+0]; printf("[%u,%u,%u]\n", (int) r, (int) g, (int) b); } } } bmp_delete(bmp); }
static void handle_request(cam_dev_t* dev, cio_handle_t* h, const char* l) { cam_err_t err; struct capture_ctx capture_ctx; const uint8_t* data; uint32_t size; uint8_t hdr[256]; capture_ctx.count = 0; capture_ctx.bmp = NULL; capture_ctx.has_captured = 0; if ((capture_ctx.bmp = bmp_create()) == NULL) goto on_error; err = cam_start_capture(dev, CAM_FORMAT_YUV420_160_120, on_frame, &capture_ctx); if (err != CAM_ERR_SUCCESS) goto on_error; err = cam_wait_capture(dev); if (err != CAM_ERR_SUCCESS) goto on_error; if (!capture_ctx.has_captured) goto on_error; size = sizeof(hdr); if (bmp_get_header(capture_ctx.bmp, hdr, &size) == -1) goto on_error; if ((data = bmp_get_data(capture_ctx.bmp)) == NULL) goto on_error; cbuf_push_back(&h->buf_out, (void*)hdr, size); cbuf_push_back(&h->buf_out, (void*)data, 160 * 120 * 3); on_error: if (capture_ctx.bmp != NULL) bmp_destroy(capture_ctx.bmp); return ; }
int run_blur(int c, char* src, char* dst, int times){ BMP* bmp = bmp_read(src); if(bmp==0) { return -1;} // open error uint8_t* data = bmp_get_data(bmp); uint32_t h = *(bmp_get_h(bmp)); uint32_t w = *(bmp_get_w(bmp)); if(w%4!=0) { return -1;} // do not support padding uint8_t* dataC = 0; if(*(bmp_get_bitcount(bmp)) == 24) { dataC = malloc(sizeof(uint8_t)*4*h*w); to32(w,h,data,dataC); } else { dataC = data; } unsigned long start, end; switch(c){ case 0: RDTSC_START(start); C_blur(w,h,dataC); RDTSC_STOP(end); break; case 1: RDTSC_START(start); ASM_blur1(w,h,dataC); RDTSC_STOP(end); break; case 2: RDTSC_START(start); ASM_blur2(w,h,dataC); RDTSC_STOP(end); break; default: // return -1; break; } unsigned long delta = end - start; printf("%lu", delta); if(*(bmp_get_bitcount(bmp)) == 24) { to24(w,h,dataC,data); free(dataC); } bmp_delete(bmp); return 0; }
int main(int argc, char* argv[]){ int i,j; // (0) leer parametros options opt; if (argc == 1) {print_help(argv[0]); return 0;} if(read_options(argc, argv, &opt)) {printf("ERROR reading parameters\n"); return 1;} int len1 = strlen(opt.file1); int len2 = strlen(opt.file2); if( strcmp(&(opt.file1[len1-4]),".bmp") || strcmp(&(opt.file2[len2-4]),".bmp") ) { printf("ERROR: nombre del archivo\n"); return -1;} // (0.1) siempre armo el summary opt.summary = (int*)malloc(sizeof(int)*256); for(i=0;i<256;i++) opt.summary[i]=0; // (1) leer imagenes BMP* bmp1 = bmp_read(opt.file1); BMP* bmp2 = bmp_read(opt.file2); if( bmp1==0 || bmp1==0 ) { printf("ERROR: no se puede abrir el archivo\n"); return -1;} // (2) check tipo de archivo if( ((BMPIH*)(bmp1->ih))->biSize != ((BMPIH*)(bmp1->ih))->biSize ) { printf("ERROR: tipo de archivo diferente\n"); return -1;} // (3) check tamaño del archivo int w1 = ((BMPIH*)(bmp1->ih))->biWidth; int h1 = ((BMPIH*)(bmp1->ih))->biHeight; int c1 = ((BMPIH*)(bmp1->ih))->biBitCount; int w2 = ((BMPIH*)(bmp2->ih))->biWidth; int h2 = ((BMPIH*)(bmp2->ih))->biHeight; int c2 = ((BMPIH*)(bmp2->ih))->biBitCount; if( w1!=w2 || h1!=h2 || c1!=c2 ) { printf("ERROR: tamaño de archivo diferente\n"); return -1;} //printf("%i=%i %i=%i %i=%i\n",w1,w2,h1,h2,c1,c2); if(w1%4!=0) { printf("ERROR: padding no soportado\n"); return -1;} // TODO: soportar padding! // (3) check el bit count TODO: only 24 o 32 if( c1!=24 && c1!=32 ) { printf("ERROR: (%i) bitcount distinto de 24 o 32\n", c1); return -1;} // (4) crear imagenes de diferencias BMP *bmpDiffR, *bmpDiffG, *bmpDiffB, *bmpDiffA; bmpDiffR = bmp_copy(bmp1,0); bmpDiffG = bmp_copy(bmp1,0); bmpDiffB = bmp_copy(bmp1,0); if(c1 == 32) bmpDiffA = bmp_copy(bmp1,0); // (5) extraer data uint8_t *data1,*data2,*dataR,*dataG,*dataB,*dataA; data1 = bmp_get_data(bmp1); data2 = bmp_get_data(bmp2); dataR = bmp_get_data(bmpDiffR); dataG = bmp_get_data(bmpDiffG); dataB = bmp_get_data(bmpDiffB); if(c1 == 32) dataA = bmp_get_data(bmpDiffA); // (6) calcular diferencias if(c1 == 32) for(j=0;j<h1;j++) { for(i=0;i<w1;i++) { int pos = (j*w1+i)*4; uint8_t R1 = data1[pos+3]; uint8_t G1 = data1[pos+2]; uint8_t B1 = data1[pos+1]; uint8_t A1 = data1[pos+0]; uint8_t R2 = data2[pos+3]; uint8_t G2 = data2[pos+2]; uint8_t B2 = data2[pos+1]; uint8_t A2 = data2[pos+0]; dataR[pos+3] = cmp(R1,R2,i,j,"R",&opt); dataR[pos+2] = dataR[pos+3]; dataR[pos+1] = dataR[pos+3]; dataR[pos+0] = 255; dataG[pos+3] = cmp(G1,G2,i,j,"G",&opt); dataG[pos+2] = dataG[pos+3]; dataG[pos+1] = dataG[pos+3]; dataG[pos+0] = 255; dataB[pos+3] = cmp(B1,B2,i,j,"B",&opt); dataB[pos+2] = dataB[pos+3]; dataB[pos+1] = dataB[pos+3]; dataB[pos+0] = 255; dataA[pos+3] = cmp(A1,A2,i,j,"A",&opt); dataA[pos+2] = dataA[pos+3]; dataA[pos+1] = dataA[pos+3]; dataA[pos+0] = 255; } } if(c1 == 24) for(j=0;j<h1;j++) { for(i=0;i<w1;i++) { int pos = (j*w1+i)*3; uint8_t R1 = data1[pos+2]; uint8_t G1 = data1[pos+1]; uint8_t B1 = data1[pos+0]; uint8_t R2 = data2[pos+2]; uint8_t G2 = data2[pos+1]; uint8_t B2 = data2[pos+0]; dataR[pos+2] = cmp(R1,R2,i,j,"R",&opt); dataR[pos+1] = dataR[pos+2]; dataR[pos+0] = dataR[pos+2]; dataG[pos+2] = cmp(G1,G2,i,j,"G",&opt); dataG[pos+1] = dataG[pos+2]; dataG[pos+0] = dataG[pos+2]; dataB[pos+2] = cmp(B1,B2,i,j,"B",&opt); dataB[pos+1] = dataB[pos+2]; dataB[pos+0] = dataB[pos+2]; } } // (7) mostrar summary if(opt.summaryop) { for(i=1;i<256;i++) if(opt.summary[i]!=0) printf("%i\t%i\n",i,opt.summary[i]); } // (8) guardar resultados if(opt.image) { char* strX = "diffX.bmp"; char* fileSto = malloc(strlen(opt.file1)+5+1); strcpy(fileSto,opt.file1); strcpy(fileSto+len1-4,strX); fileSto[len1]='R'; bmp_save(fileSto,bmpDiffR); fileSto[len1]='G'; bmp_save(fileSto,bmpDiffG); fileSto[len1]='B'; bmp_save(fileSto,bmpDiffB); fileSto[len1]='A'; if(c1 == 32) bmp_save(fileSto,bmpDiffA); // (8.1) borrar las imagenes bmp_delete(bmp1); bmp_delete(bmp2); bmp_delete(bmpDiffR); bmp_delete(bmpDiffG); bmp_delete(bmpDiffB); if(c1 == 32) bmp_delete(bmpDiffA); } // (9) retorno error si encontre una diferencia for(i=opt.epsilon;i<256;i++) if(opt.summary[i]>0) return -1; return 0; }
int main(){ /* ======================================================================= */ /* === EJ 1 : crear un bmp de 24 bits de 100x100 y dibujar un patron bayer */ // creo el header de una imagen de 100x100 de 24 bits BMPIH* imgh1 = get_BMPIH(100,100); // crea una imagen bmp inicializada BMP* bmp1 = bmp_create(imgh1,1); // obtengo la data y dibujo el patron bayer uint8_t* data1 = bmp_get_data(bmp1); int i,j; for(j=0;j<100;j=j+2) { for(i=0;i<100;i=i+2) { data1[j*300+3*i+1] = 0xff; data1[j*300+3*i+3] = 0xff; } for(i=0;i<100;i=i+2) { data1[j*300+300+3*i+2] = 0xff; data1[j*300+300+3*i+4] = 0xff; } } // guardo la imagen bmp_save(FILE1, bmp1); // borrar bmp bmp_delete(bmp1); /* ======================================================================= */ /* === EJ 2 : crear un bmp de 32 bits de 100x100 y fondo blanco en degrade */ // creo el encavezado de una imagen de 640x480 de 32 bits BMPV5H* imgh2 = get_BMPV5H(100,100); // crea una imagen bmp no inicializada BMP* bmp2 = bmp_create(imgh2,0); // obtengo la data y dibujo el degrade uint8_t* data2 = bmp_get_data(bmp2); for(j=0;j<100;j++) { for(i=0;i<100;i++) { data2[j*400+i*4+0] = (uint8_t)(((float)(i+j))*(256.0/200.0)); data2[j*400+i*4+1] = 0xff; data2[j*400+i*4+2] = 0xff; data2[j*400+i*4+3] = 0xff; } } // guardo la imagen bmp_save(FILE2, bmp2); // borrar bmp bmp_delete(bmp2); /* ======================================================================= */ /* === EJ 3 : crear un bmp con el mapa de bits de bmp1 y el alpha de bmp2 */ // Abro los dos archivos BMP* bmp1n = bmp_read(FILE1); BMP* bmp2n = bmp_read(FILE2); // copio la imagen con transparecia sin datos BMP* bmpNEW = bmp_copy(bmp2n, 0); // obtengo datos de new y las combino uint8_t* data1n = bmp_get_data(bmp1n); uint8_t* data2n = bmp_get_data(bmp2n); uint8_t* dataNEW = bmp_get_data(bmpNEW); for(j=0;j<100;j++) { for(i=0;i<100;i++) { dataNEW[j*400+i*4+0] = data2n[j*400+i*4+0]; dataNEW[j*400+i*4+1] = data1n[j*300+i*3+0]; dataNEW[j*400+i*4+2] = data1n[j*300+i*3+1]; dataNEW[j*400+i*4+3] = data1n[j*300+i*3+2]; } } // guardo la imagen bmp_save(FILE3, bmpNEW); // borrar bmp bmp_delete(bmp1n); bmp_delete(bmp2n); bmp_delete(bmpNEW); return 0; }
int run_merge(int c, char* src1, char* src2, char* dst, float value, int times){ if(value>1) value=1; else if(value<0) value=0; BMP* bmp1 = bmp_read(src1); BMP* bmp2 = bmp_read(src2); if(bmp1==0 || bmp2==0) { return -1;} // open error uint8_t* data1 = bmp_get_data(bmp1); uint8_t* data2 = bmp_get_data(bmp2); uint32_t h1 = *(bmp_get_h(bmp1)); uint32_t w1 = *(bmp_get_w(bmp1)); uint32_t h2 = *(bmp_get_h(bmp2)); uint32_t w2 = *(bmp_get_w(bmp2)); if(w1%4!=0 || w2%4!=0) { return -1;} // do not support padding if( w1!=w2 || h1!=h2 ) { return -1;} // different image size uint8_t* data1C = 0; uint8_t* data2C = 0; if(*(bmp_get_bitcount(bmp1)) == 24) { data1C = malloc(sizeof(uint8_t)*4*h1*w1); data2C = malloc(sizeof(uint8_t)*4*h2*w2); to32(w1,h1,data1,data1C); to32(w2,h2,data2,data2C); } else { data1C = data1; data2C = data2; } unsigned long start, end; switch(c){ case 0: RDTSC_START(start); C_merge(w1,h1,data1C,data2C,value); RDTSC_STOP(end); break; case 1: RDTSC_START(start); ASM_merge1(w1,h1,data1C,data2C,value); RDTSC_STOP(end); break; case 2: RDTSC_START(start); ASM_merge2(w1,h1,data1C,data2C,value); RDTSC_STOP(end); break; default: return -1; break; } unsigned long delta = end - start; printf("%lu", delta); if(*(bmp_get_bitcount(bmp1)) == 24) { to24(w1,h1,data1C,data1); free(data1C); free(data2C); } bmp_delete(bmp1); bmp_delete(bmp2); return 0; }
static cam_err_t on_frame(cam_dev_t* dev, cam_frame_t* frame, void* ctx) { struct capture_ctx* capture_ctx = ctx; uint32_t width; uint32_t height; cam_err_t err; void* data; if (!capture_ctx->count) { /* wait for a complete frame */ capture_ctx->count = 1; err = CAM_ERR_CONTINUE; goto on_error; } switch (frame->format) { case CAM_FORMAT_YUV420_160_120: width = 160; height = 120; break; case CAM_FORMAT_YUV420_320_240: width = 320; height = 240; break; case CAM_FORMAT_YUV420_640_480: width = 640; height = 480; break; default: err = CAM_ERR_NOT_SUPPORTED; goto on_error; break; } if (bmp_set_format(capture_ctx->bmp, 24, width, height) == -1) { err = CAM_ERR_FAILURE; goto on_error; } if ((data = bmp_get_data(capture_ctx->bmp)) == NULL) { err = CAM_ERR_RESOURCE; goto on_error; } transform_yuv420_to_rgb24(data, frame->data, width, height); transform_vflip_rgb24(data, width, height); capture_ctx->has_captured = 1; /* next frame */ err = CAM_ERR_SUCCESS; on_error: return err; }