Exemplo n.º 1
0
static int fill(video_generator* gen, int x, int y, int w, int h, int r, int g, int b) {

    // Y
    int yc = RGB2Y(r,g,b);
    int uc = RGB2U(r,g,b);
    int vc = RGB2V(r,g,b);
    int j = 0;

    // UV
    int xx = x / 2;
    int yy = y / 2;
    int half_w = gen->width / 2;
    int half_h = gen->height / 2;
    int hh = h / 2;
    int ww = w / 2;

    // y
    for (j = y; j < (y + h); ++j) {
        memset(gen->y + j * gen->width + x, yc, w);
    }

    // u and v
    for (j = yy; j < (yy + hh); ++j) {
        memset(gen->u + j * half_w + xx, uc, (ww));
        memset(gen->v + j * half_w + xx, vc, (ww));
    }

    return 0;
}
/* Computes the pixel value after adjusting the white balance to the current
 * one. The input the y, u, v channel of the pixel and the adjusted value will
 * be stored in place. The adjustment is done in RGB space.
 */
void EmulatedCameraDevice::changeWhiteBalance(uint8_t& y,
                                              uint8_t& u,
                                              uint8_t& v) const {
    float r_scale = mWhiteBalanceScale[0];
    float b_scale = mWhiteBalanceScale[2];
    int r = static_cast<float>(YUV2R(y, u, v)) / r_scale;
    int g = YUV2G(y, u, v);
    int b = static_cast<float>(YUV2B(y, u, v)) / b_scale;

    y = RGB2Y(r, g, b);
    u = RGB2U(r, g, b);
    v = RGB2V(r, g, b);
}
Exemplo n.º 3
0
static void reduceImage(uint8_t * image,uint8_t * found_colors,int row,unsigned offsetPal,Fl_Progress *progress,Fl_Window*pwin,unsigned maxCol,unsigned yuv,unsigned alg,bool isSprite=false,bool ditherBefore=true){
	if(progress)
		progress->maximum(1.0);
	unsigned off2=offsetPal*2;
	unsigned off3=offsetPal*3;
	unsigned colors_found;
	unsigned w,h;
	unsigned maxPal=maxCol;
	unsigned msprt=curSpritemeta;
	if(isSprite){
		w=currentProject->ms->sps[msprt].width(curSpritegroup);
		h=currentProject->ms->sps[msprt].height(curSpritegroup);
		currentProject->ms->sps[msprt].spriteGroupToImage(image,curSpritegroup,row,false);
	}else{
		w=currentProject->tms->maps[currentProject->curPlane].mapSizeW;
		h=currentProject->tms->maps[currentProject->curPlane].mapSizeHA;
		w*=currentProject->tileC->sizew;
		h*=currentProject->tileC->sizeh;
		currentProject->tms->maps[currentProject->curPlane].truecolor_to_image(image,row,false);
	}
	if(progress){
		progress->label("Dithering to colorspace");
		Fl::check();
	}
	if((!yuv)&&ditherBefore)
		ditherImage(image,w,h,false,true);
	if(progress){
		progress->label("Quantizing image");
		Fl::check();
	}
	colors_found=count_colors(image,w,h,&found_colors[0],false);
	printf("Unique colors %d\n",colors_found);
	if (colors_found <= maxCol){
		printf("%d colors\n",colors_found);
		unsigned offsetTmp=offsetPal;
		for (unsigned x=0;x<colors_found;x++){
			uint_fast8_t r,g,b;
againFun:
			if (currentProject->pal->palType[offsetTmp]){
				++offsetTmp;
				if(offsetTmp>=maxPal)
					goto actullyNeededReduction;
				goto againFun;
			}
			r=found_colors[(x*3)];
			g=found_colors[(x*3)+1];
			b=found_colors[(x*3)+2];
			printf("R=%d G=%d B=%d\n",r,g,b);
			if(currentProject->pal->shouldAddCol(offsetTmp,r,g,b,isSprite)){
				currentProject->pal->rgbToEntry(r,g,b,offsetTmp);
				currentProject->pal->updateRGBindex(offsetTmp);
				++offsetTmp;
			}
		}
		if(currentProject->gameSystem==NES)
			updateEmphesis();
		if(window)
			window->redraw();
	}else{
actullyNeededReduction:
		printf("More than %d colors reducing to %d colors\n",maxCol,maxCol);
		uint8_t user_pal[3][256];			
		uint8_t rgb_pal2[768];
		uint8_t rgb_pal3[768];
		unsigned colorz=maxCol;
		bool can_go_again=true;
		uint8_t*imageuse;
		uint8_t*output;
		if(alg==1)
			output=(uint8_t*)malloc(w*h*3);
		if(yuv){
			imageuse=(uint8_t*)malloc(w*h*3);
			uint32_t x,y;
			uint8_t*imageptr=image;
			uint8_t*outptr=imageuse;
			for(y=0;y<h;y++){
				for(x=0;x<w;x++){
					if(yuv==2){
						outptr[0]=CRGB2Y(imageptr[0],imageptr[1],imageptr[2]);
						outptr[1]=CRGB2Cb(imageptr[0],imageptr[1],imageptr[2]);
						outptr[2]=CRGB2Cr(imageptr[0],imageptr[1],imageptr[2]);
					}else{
						outptr[0]=RGB2Y(imageptr[0],imageptr[1],imageptr[2]);
						outptr[1]=RGB2U(imageptr[0],imageptr[1],imageptr[2]);
						outptr[2]=RGB2V(imageptr[0],imageptr[1],imageptr[2]);
					}
					imageptr+=3;
					outptr+=3;
				}
			}
		}else
			imageuse=image;
try_again_color:
		switch(alg){
			case 4:
				dl1quant(imageuse,w,h,colorz,user_pal);
			break;
			case 3:
				wu_quant(imageuse,w,h,colorz,user_pal);
			break;
			case 2:
				NEU_wrapper(w,h,imageuse,colorz,user_pal);
			break;
			case 1:
				scolorq_wrapper(imageuse,output,user_pal,w,h,colorz);
			break;
			default:
				dl3quant(imageuse,w,h,colorz,user_pal,true,progress);/*this uses denesis lee's v3 color quant which is found at http://www.gnu-darwin.org/www001/ports-1.5a-CURRENT/graphics/mtpaint/work/mtpaint-3.11/src/quantizer.c*/
		}
		for (unsigned x=0;x<colorz;x++){
			unsigned r,g,b;
			if(yuv){
				if(yuv==2){
					r=CYCbCr2R(user_pal[0][x],user_pal[1][x],user_pal[2][x]);
					g=CYCbCr2G(user_pal[0][x],user_pal[1][x],user_pal[2][x]);
					b=CYCbCr2B(user_pal[0][x],user_pal[1][x],user_pal[2][x]);
				}else{
					r=YUV2R(user_pal[0][x],user_pal[1][x],user_pal[2][x]);
					g=YUV2G(user_pal[0][x],user_pal[1][x],user_pal[2][x]);
					b=YUV2B(user_pal[0][x],user_pal[1][x],user_pal[2][x]);
				}
			}else{
				r=user_pal[0][x];
				g=user_pal[1][x];
				b=user_pal[2][x];
			}
			switch(currentProject->gameSystem){
				case segaGenesis:
					r=nearest_color_index(r);
					g=nearest_color_index(g);
					b=nearest_color_index(b);
					rgb_pal2[(x*3)]=palTab[r];
					rgb_pal2[(x*3)+1]=palTab[g];
					rgb_pal2[(x*3)+2]=palTab[b];
				break;
				case NES:
					{uint8_t temp=currentProject->pal->to_nes_color_rgb(r,g,b);
					uint32_t temp_rgb = nesPalToRgb(temp);
					rgb_pal2[(x*3)]=(temp_rgb>>16)&255;
					rgb_pal2[(x*3)+1]=(temp_rgb>>8)&255;
					rgb_pal2[(x*3)+2]=temp_rgb&255;}
				break;
				case masterSystem:
				case gameGear:
					{const uint8_t*palUseTab=currentProject->gameSystem==gameGear?palTabGameGear:palTabMasterSystem;
					unsigned colsTab=currentProject->gameSystem==gameGear?16:4;
					r=nearestOneChannel(r,palUseTab,colsTab);
					g=nearestOneChannel(g,palUseTab,colsTab);
					b=nearestOneChannel(b,palUseTab,colsTab);
					rgb_pal2[(x*3)]=palUseTab[r];
					rgb_pal2[(x*3)+1]=palUseTab[g];
					rgb_pal2[(x*3)+2]=palUseTab[b];}
				break;
				default:
					show_default_error
			}
		}
		unsigned new_colors = count_colors(rgb_pal2,colorz,1,rgb_pal3);
		printf("Unique colors in palette %u\n",new_colors);
			if (new_colors < maxCol){
				if (can_go_again == true){
					if (colorz != 512)
						colorz++;
					else
						can_go_again=false;
					char tmp[1024];
					snprintf(tmp,1024,"Found only %d colors trying again with %d",new_colors,colorz);
					tmp[sizeof(tmp)-1]=0;
					if(pwin){
						pwin->copy_label(tmp);
						Fl::check();
					}
					puts(tmp);
					goto try_again_color;
				}
			}
		if (new_colors > maxCol){
			can_go_again=false;
			if(pwin)
				pwin->label("Too many colors");
			colorz--;
			goto try_again_color;
		}
		unsigned offsetTmp=offsetPal;
		for (unsigned x=0;x<maxCol;x++){
againNerd:
			if (currentProject->pal->palType[offsetTmp]){
				++offsetTmp;
				if(offsetTmp>(maxPal+offsetPal)){
					if(maxCol>1){
						--colorz;
						printf("Needed to reduce colors generated due to locked colors %u\n",maxCol);
					}else{
						fl_alert("Cannot reduce maximum colors to make this happen...aborting");
						return;	
					}
					goto try_again_color;
				}
				goto againNerd;
			}
			unsigned r=rgb_pal3[x*3],g=rgb_pal3[x*3+1],b=rgb_pal3[x*3+2];
			if(currentProject->pal->shouldAddCol(offsetTmp,r,g,b,isSprite)){
				memcpy(currentProject->pal->rgbPal+(offsetTmp*3),rgb_pal3+(x*3),3);
				currentProject->pal->rgbToEntry(r,g,b,offsetTmp);
				++offsetTmp;
			}
		}
		if(currentProject->gameSystem==NES)
			updateEmphesis();
		if(alg==1){
			if(isSprite)
				currentProject->ms->sps[msprt].spriteImageToTiles(output,curSpritegroup,row,false);
			else
				currentProject->tms->maps[currentProject->curPlane].truecolorimageToTiles(output,row,false);
			free(output);
		}
		if(yuv)
			free(imageuse);
	}
}
Exemplo n.º 4
0
void WebMEncoder::convertFrame(unsigned char *inputImage,int inputStride) {
    int ii,j;
    //printf("IMAGE INFO: %d %d %d %d %d %d %d %d\n",raw.stride[0],raw.stride[1],raw.stride[2],raw.bps,raw.w,raw.h,raw.fmt,VPX_IMG_FMT_YV12);
    {
        unsigned char *yData = raw.planes[0];
        unsigned char *uData = raw.planes[1];
        unsigned char *vData = raw.planes[2];
        
        memset(uData,0,(width*height)>>2);
        memset(vData,0,(width*height)>>2);
        
        int stride=3;
        switch(inputVideoFormat) {
        case IVF_RGB:
            stride = 3;
            break;
        case IVF_RGBA:
            stride = 4;
            break;
        }
        int fullYIndex=0;

        int fullRGBTLIndex=0;
        int fullRGBTRIndex=stride;
        int fullRGBBLIndex=stride*inputStride;
        int fullRGBBRIndex=stride*(inputStride+1);

        int halfIndex=0;
        int halfHeight = height>>1;
        int halfWidth = width>>1;
        for(ii=0;ii<halfHeight;ii++) {
            for(j=0;j<halfWidth;j++) {
                /*
                  image[fullRGBIndex]=255;
                  image[fullRGBIndex+1]=0;
                  image[fullRGBIndex+2]=0;
                  image[fullRGBIndex+stride]=255;
                  image[fullRGBIndex+stride+1]=0;
                  image[fullRGBIndex+stride+2]=0;
                  image[fullRGBIndex+stride*width]=255;
                  image[fullRGBIndex+stride*width+1]=0;
                  image[fullRGBIndex+stride*width+2]=0;
                  image[fullRGBIndex+stride*width+stride]=255;
                  image[fullRGBIndex+stride*width+stride+1]=0;
                  image[fullRGBIndex+stride*width+stride+2]=0;
                */

                RGB2Y(yData[fullYIndex],inputImage[fullRGBTLIndex+2],inputImage[fullRGBTLIndex+1],inputImage[fullRGBTLIndex])
                    RGB2Y(yData[fullYIndex+1],inputImage[fullRGBTRIndex+2],inputImage[fullRGBTRIndex+1],inputImage[fullRGBTRIndex])
                    RGB2Y(yData[fullYIndex+width],inputImage[fullRGBBLIndex+2],inputImage[fullRGBBLIndex+1],inputImage[fullRGBBLIndex])
                    RGB2Y(yData[fullYIndex+width+1],inputImage[fullRGBBRIndex+2],inputImage[fullRGBBRIndex+1],inputImage[fullRGBBRIndex])

                    RGB2U(uData[halfIndex],\
                          inputImage[fullRGBTLIndex+2],inputImage[fullRGBTLIndex+1],inputImage[fullRGBTLIndex],\
                          inputImage[fullRGBTRIndex+2],inputImage[fullRGBTRIndex+1],inputImage[fullRGBTRIndex],\
                          inputImage[fullRGBBLIndex+2],inputImage[fullRGBBLIndex+1],inputImage[fullRGBBLIndex],\
                          inputImage[fullRGBBRIndex+2],inputImage[fullRGBBRIndex+1],inputImage[fullRGBBRIndex]\
                        );

                RGB2V(vData[halfIndex],\
                      inputImage[fullRGBTLIndex+2],inputImage[fullRGBTLIndex+1],inputImage[fullRGBTLIndex],\
                      inputImage[fullRGBTRIndex+2],inputImage[fullRGBTRIndex+1],inputImage[fullRGBTRIndex],\
                      inputImage[fullRGBBLIndex+2],inputImage[fullRGBBLIndex+1],inputImage[fullRGBBLIndex],\
                      inputImage[fullRGBBRIndex+2],inputImage[fullRGBBRIndex+1],inputImage[fullRGBBRIndex]\
                    );

                //yData[fullYIndex] = yData[fullYIndex+1] = yData[fullYIndex+width] = yData[fullYIndex+width+1] = 255;
                //uData[halfIndex] = 0;
                //vData[halfIndex] = 127;

                fullYIndex+=2;

                fullRGBTLIndex += stride*2;
                fullRGBTRIndex += stride*2;
                fullRGBBLIndex += stride*2;
                fullRGBBRIndex += stride*2;

                halfIndex++;
            }
            fullYIndex += width;

            fullRGBTLIndex += stride*((inputStride-width)+inputStride);
            fullRGBTRIndex += stride*((inputStride-width)+inputStride);
            fullRGBBLIndex += stride*((inputStride-width)+inputStride);
            fullRGBBRIndex += stride*((inputStride-width)+inputStride);
        }
    }
}
Exemplo n.º 5
0
void I3C_Converter::Pixel2YUV(Pixel *pixel, YUV *yuv)
{
    yuv->Y = RGB2Y(pixel->red, pixel->green, pixel->blue);
    yuv->U = RGB2U(pixel->red, pixel->green, pixel->blue);
    yuv->V = RGB2V(pixel->red, pixel->green, pixel->blue);
}
Exemplo n.º 6
0
/* generates a new frame and stores it in the y, u and v members */
int video_generator_update(video_generator* g) {

    double perc;
    int is_bip, is_bop;
    int text_w, text_x, text_y, i;
    int32_t bar_h, time, speed, start_y, nlines, h;
    uint64_t days, hours, minutes, seconds;
    uint32_t stride, end_y;
    char timebuf[512] = { 0 } ;
    int text_r, text_g, text_b;
    int rc, gc, bc, yc, uc, vc, dx;
    int colors[] = {
        255, 255, 255,  // white
        255, 255, 0,    // yellow
        0,   255, 255,  // cyan
        0,   255, 0,    // green
        255, 0,   255,  // magenta
        255, 0,   0,    // red
        0,   0,   255   // blue
    };

    if (!g) {
        return -1;
    }
    if (!g->width) {
        return -2;
    }
    if (!g->height) {
        return -3;
    }

    text_r = 0;
    text_g = 0;
    text_b = 0;

    h = g->height - 1;
    bar_h = g->height / 5;
    start_y = -bar_h + (g->perc * (h + bar_h));

    /* how many lines of the bar are visible */
    if (start_y < 0) {
        nlines = bar_h + start_y;
        start_y = 0;
    }
    else if(start_y + bar_h > h) {
        nlines = h - start_y;
    }
    else {
        nlines = bar_h;
    }

    /* increment step */
    g->perc += g->step;
    if (g->perc >= (1.0)) {
        g->perc = 0.0;
    }

    if (nlines + start_y > g->height || nlines < 0 || start_y < 0 || start_y >= g->height) {
        printf("Error: this shouldn't happen.. writing outside the buffer: %d, %d, %d\n", nlines, (nlines + start_y), start_y);
        return -1;
    }

    /* reset */
    memset(g->y, 0x00, g->ybytes);
    memset(g->u, 0x00, g->ubytes);
    memset(g->v, 0x00, g->vbytes);

    for (i = 0; i < 7; ++i) {
        dx = i * 3;
        rc = colors[dx + 0];
        gc = colors[dx + 1];
        bc = colors[dx + 2];
        fill(g, i * (g->width / 7), 0, (g->width / 7), g->height, rc, gc, bc);
    }

    rc = 255 - (g->perc * 255);
    gc = 30 + (g->perc * 235);
    bc = 150 + (g->perc * 205);
    yc = RGB2Y(rc, gc, bc);
    uc = RGB2U(rc, gc, bc);
    vc = RGB2V(rc, gc, bc);

    /* fill y channel */
    for (i = start_y; i < (start_y + nlines); ++i) {
        memset(g->y + (i * g->width), yc, g->width);
    }

    /* fill u and v channel */
    start_y = start_y / 2;
    stride = g->width * 0.5;
    end_y = start_y + nlines/ 2;

    for (i = start_y; i < end_y; ++i) {
        memset(g->u + i * stride, uc, stride);
        memset(g->v + i * stride, vc, stride);
    }

    /* draw blip/blop visuals. */
    if (NULL != g->audio_buffer) {
        mutex_lock(&g->audio_mutex);
        {
            is_bop = g->audio_is_bop;
            is_bip = g->audio_is_bip;

        }
        mutex_unlock(&g->audio_mutex);

        if (is_bip == 1) {
            text_r = 0;
            text_g = 0;
            text_b = 255;
        }
        if (is_bop == 1) {
            text_r = 255;
            text_g = 0;
            text_b = 0;
        }
    }

    seconds = (g->frame/ g->fps_den);
    minutes = (seconds / 60);
    hours = minutes / 60;
    days = hours / 24;
    minutes %= 60;
    seconds %= 60;
    hours %= 24;
    text_w = 360; /* manually measured */
    text_x = (g->width / 2) - (text_w / 2);
    text_y = (g->height / 2) - 50;

    fill(g, text_x, text_y, text_w, 100, text_r, text_g, text_b);

    sprintf(timebuf, "%03llu:%02llu:%02llu:%02llu", days, hours, minutes, seconds);
    add_number_string(g, timebuf, text_x + 20, text_y + 20);

    g->frame++;
    return 0;
}