int C4PlayerList::CheckColorDw(DWORD dwColor, C4Player *pExclude) { // maximum difference int iDiff=255+255+255; // check all player's color difference for (C4Player *pPlr=First; pPlr; pPlr=pPlr->Next) if (pPlr != pExclude) { // get color DWORD dwClr2=pPlr->ColorDw; // assign difference, if less than smallest difference found iDiff=std::min(iDiff, Abs(GetBlueValue(dwColor) - GetBlueValue(dwClr2)) + Abs(GetGreenValue(dwColor) - GetGreenValue(dwClr2)) + Abs(GetRedValue(dwColor) - GetRedValue(dwClr2))); } // return the difference return iDiff; }
bool ClrByOwner(DWORD &dwClr) // new style, based on Microsoft Knowledge Base Article - 29240 { int H,L,S; WORD R,G,B; BYTE cMax,cMin; WORD Rdelta,Gdelta,Bdelta; // get RGB R = GetRedValue(dwClr); G = GetGreenValue(dwClr); B = GetBlueValue(dwClr); // calculate lightness cMax = std::max<int>(std::max<int>(R,G),B); cMin = std::min<int>(std::min<int>(R,G),B); L = ( ((cMax+cMin)*HLSMAX) + RGBMAX )/(2*RGBMAX); // achromatic case if (cMax == cMin) { S = 0; H = (HLSMAX*2/3); } // chromatic case else { // saturation if (L <= (HLSMAX/2)) S = ( ((cMax-cMin)*HLSMAX) + ((cMax+cMin)/2) ) / (cMax+cMin); else S = ( ((cMax-cMin)*HLSMAX) + ((2*RGBMAX-cMax-cMin)/2) ) / (2*RGBMAX-cMax-cMin); // hue Rdelta = ( ((cMax-R)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin); Gdelta = ( ((cMax-G)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin); Bdelta = ( ((cMax-B)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin); if (R == cMax) H = Bdelta - Gdelta; else if (G == cMax) H = (HLSMAX/3) + Rdelta - Bdelta; else H = ((2*HLSMAX)/3) + Gdelta - Rdelta; if (H < 0) H += HLSMAX; if (H > HLSMAX) H -= HLSMAX; } // Not blue if (!(Inside(H, 145, 175) && (S > 100))) return false; // It's blue: make it gray BYTE b = GetBlueValue(dwClr); dwClr = RGBA(b, b, b, 0) | (dwClr & 0xff000000); return true; }
bool CPNGFile::SetPix(int iX, int iY, DWORD dwValue) { // image created? if (!pImageData) return false; // set pixel value unsigned char *pPix=pImageData+iY*iRowSize+iX*iPixSize; switch (iClrType) { case PNG_COLOR_TYPE_RGB: // RGB: set r, g and b values pPix[0] = GetBlueValue(dwValue); pPix[1] = GetGreenValue(dwValue); pPix[2] = GetRedValue(dwValue); return true; case PNG_COLOR_TYPE_RGB_ALPHA: // RGBA: simply set in mem *(DWORD *) pPix = dwValue; return true; } return false; }
void C4BMP256Info::Set(int iWdt, int iHgt, CStdPalette *Palette) { Default(); // Set header Head.bfType=*((const WORD*)"BM"); Head.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+DWordAligned(iWdt)*iHgt; Head.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD); // Set bitmap info Info.biSize=sizeof(BITMAPINFOHEADER); Info.biWidth=iWdt; Info.biHeight=iHgt; Info.biPlanes=1; Info.biBitCount=8; Info.biCompression=0; Info.biSizeImage=iWdt*iHgt; Info.biClrUsed=Info.biClrImportant=256; // Set palette for (int cnt=0; cnt<256; cnt++) { Colors[cnt].rgbRed = GetRedValue(Palette->Colors[cnt]); Colors[cnt].rgbGreen = GetGreenValue(Palette->Colors[cnt]); Colors[cnt].rgbBlue = GetBlueValue(Palette->Colors[cnt]); } }
void CStdGL::FillBG(DWORD dwClr) { if (!pCurrCtx) return; glClearColor((float)GetRedValue(dwClr)/255.0f, (float)GetGreenValue(dwClr)/255.0f, (float)GetBlueValue(dwClr)/255.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
bool C4LandscapeRenderGL::LoadScaler(C4GroupSet *pGroups) { // Search for scaler C4Group *pGroup = pGroups->FindEntry(C4CFN_LandscapeScaler); if(!pGroup) return false; // Load scaler from group if(!fctScaler.Load(*pGroup, C4CFN_LandscapeScaler, C4FCT_Full, C4FCT_Full, false, 0)) return false; // Check size const int iOrigWdt = 8 * 3, iOrigHgt = 4 * 8 * 3; const int iFactor = fctScaler.Wdt / iOrigWdt; if(fctScaler.Wdt != iFactor * iOrigWdt || fctScaler.Hgt != iFactor * iOrigHgt) { LogF(" gl: Unexpected scaler size - should be multiple of %dx%d!", iOrigWdt, iOrigHgt); return false; } // Walk through all lookups we have in the texture and decide where // to look for the "other" pixel. This might not be unique later on, // so it is a good idea to have a proper priority order here. fctScaler.Surface->Lock(); int i; for (i = 0; i < 8 * 4 * 8; i++) { // Decode from ID what pixels are expected to be set in this case enum Px { NW, N, NE, W, E, SW, S, SE, X }; int p_x[9] = { -1, 0, 1, -1, 1, -1, 0, 1, 0 }; int p_y[9] = { -1, -1, -1, 0, 0, 1, 1, 1, 0 }; bool pxAt[X]; for(int j = 0; j < X; j++) pxAt[j] = !!(i & (1 << j)); // Oc = octant borders. Set up arrays to get righthand border // of an octant, in a way that we can easily rotate further. enum Oc { NWW, NEE, SWW, SEE, NNW, NNE, SSW, SSE }; int p2a[8] = { 5, 6, 7, 4, 0, 3, 2, 1 }; Oc a2o[8] = { SEE, SSE, SSW, SWW, NWW, NNW, NNE, NEE }; // Decide in which octant we want to interpolate towards // which pixel. Pick the nearest unset pixel using a special // priority order. Px opx[8] = { X,X,X,X,X,X,X,X }; #define INTERPOLATE(x,da) do { \ int y = a2o[(8+p2a[x]+(da)) % 8];\ if (!pxAt[x] && opx[y] == X) opx[y] = x; \ } while(false) for(int j = 0; j < 4; j++) { // vertical INTERPOLATE(N, j); INTERPOLATE(N, -j-1); INTERPOLATE(S, j); INTERPOLATE(S, -j-1); // horizontal INTERPOLATE(W, j); INTERPOLATE(W, -j-1); INTERPOLATE(E, j); INTERPOLATE(E, -j-1); // diagonals INTERPOLATE(NW, j); INTERPOLATE(NW, -j-1); INTERPOLATE(SW, j); INTERPOLATE(SW, -j-1); INTERPOLATE(NE, j); INTERPOLATE(NE, -j-1); INTERPOLATE(SE, j); INTERPOLATE(SE, -j-1); } // Decide in which octants we will not interpolate normals. // It doesn't make sense when there's another material in that // general direction, as then the bias of that will factor into // the interpolation, giving bright borders on dark shading, // and vice-versa. bool noNormals[8]; noNormals[NNW] = noNormals[NWW] = !pxAt[W] || !pxAt[NW] || !pxAt[N]; noNormals[NNE] = noNormals[NEE] = !pxAt[E] || !pxAt[NE] || !pxAt[N]; noNormals[SSW] = noNormals[SWW] = !pxAt[W] || !pxAt[SW] || !pxAt[S]; noNormals[SSE] = noNormals[SEE] = !pxAt[E] || !pxAt[SE] || !pxAt[S]; // Set blue and green components to relative coordinates of // "other" pixel, and alpha to mix param for normals const int x0 = (i % 8) * 3 * iFactor; const int y0 = (i / 8) * 3 * iFactor; const int iPxs = 3 * iFactor; int y, x; for(y = 0; y < iPxs; y++) { for(x = 0; x < iPxs; x++) { // Find out in which octagon we are int oct = 0; if(2 * x >= iPxs) oct+=1; if(2 * y >= iPxs) oct+=2; if((x >= y) != (x >= iPxs - y)) oct+=4; // Get pixel, do processing DWORD pix = fctScaler.Surface->GetPixDw(x0+x, y0+y, false); BYTE val = GetGreenValue(pix); if(val >= 250) val = 255; BYTE bx = 64 * (p_x[opx[oct]] + 1); BYTE by = 64 * (p_y[opx[oct]] + 1); BYTE bn = (noNormals[oct] ? 255 : 1); fctScaler.Surface->SetPixDw(x0+x, y0+y, RGBA(val, bx, by, bn)); } } } return fctScaler.Surface->Unlock(); }
void BlotScaledImageSizedEx ( ImageFile *pifDest, ImageFile *pifSrc , int32_t xd, int32_t yd , uint32_t wd, uint32_t hd , int32_t xs, int32_t ys , uint32_t ws, uint32_t hs , uint32_t nTransparent , uint32_t method, ... ) // integer scalar... 0x10000 = 1 { CDATA *po, *pi; static uint32_t lock; uint32_t oo; uint32_t srcwidth; int errx, erry; uint32_t dhd, dwd, dhs, dws; va_list colors; va_start( colors, method ); //lprintf( WIDE("Blot enter (%d,%d)"), _wd, _hd ); if( nTransparent > ALPHA_TRANSPARENT_MAX ) { return; } if( !pifSrc || !pifDest || !pifSrc->image //|| !pifDest->image || !wd || !hd || !ws || !hs ) { return; } if( ( xd > ( pifDest->x + pifDest->width ) ) || ( yd > ( pifDest->y + pifDest->height ) ) || ( ( xd + (signed)wd ) < pifDest->x ) || ( ( yd + (signed)hd ) < pifDest->y ) ) { return; } dhd = hd; dhs = hs; dwd = wd; dws = ws; // ok - how to figure out how to do this // need to update the position and width to be within the // the bounds of pifDest.... //lprintf(" begin scaled output..." ); errx = -(signed)dwd; erry = -(signed)dhd; if( xd < pifDest->x ) { while( xd < pifDest->x ) { errx += (signed)dws; while( errx >= 0 ) { errx -= (signed)dwd; ws--; xs++; } wd--; xd++; } } //Log8( WIDE("Blot scaled params: %d %d %d %d / %d %d %d %d "), // xs, ys, ws, hs, xd, yd, wd, hd ); if( yd < pifDest->y ) { while( yd < pifDest->y ) { erry += (signed)dhs; while( erry >= 0 ) { erry -= (signed)dhd; hs--; ys++; } hd--; yd++; } } //Log8( WIDE("Blot scaled params: %d %d %d %d / %d %d %d %d "), // xs, ys, ws, hs, xd, yd, wd, hd ); if( ( xd + (signed)wd ) > ( pifDest->x + pifDest->width) ) { //int newwd = TOFIXED(pifDest->width); //ws -= ((int64_t)( (int)wd - newwd)* (int64_t)ws )/(int)wd; wd = ( pifDest->x + pifDest->width ) - xd; } //Log8( WIDE("Blot scaled params: %d %d %d %d / %d %d %d %d "), // xs, ys, ws, hs, xd, yd, wd, hd ); if( ( yd + (signed)hd ) > (pifDest->y + pifDest->height) ) { //int newhd = TOFIXED(pifDest->height); //hs -= ((int64_t)( hd - newhd)* hs )/hd; hd = (pifDest->y + pifDest->height) - yd; } if( (int32_t)wd <= 0 || (int32_t)hd <= 0 || (int32_t)ws <= 0 || (int32_t)hs <= 0 ) { return; } //Log9( WIDE("Image locations: %d(%d %d) %d(%d) %d(%d) %d(%d)") // , xs, FROMFIXED(xs), FIXEDPART(xs) // , ys, FROMFIXED(ys) // , xd, FROMFIXED(xd) // , yd, FROMFIXED(yd) ); #ifdef _INVERT_IMAGE // set pointer in to the starting x pixel // on the last line of the image to be copied pi = IMG_ADDRESS( pifSrc, (xs), (ys) ); po = IMG_ADDRESS( pifDest, (xd), (yd) ); oo = 4*(-((signed)wd) - (pifDest->pwidth) ); // w is how much we can copy... // adding in multiple of 4 because it's C... srcwidth = -(4* pifSrc->pwidth); #else // set pointer in to the starting x pixel // on the first line of the image to be copied... pi = IMG_ADDRESS( pifSrc, (xs), (ys) ); po = IMG_ADDRESS( pifDest, (xd), (yd) ); oo = 4*(pifDest->pwidth - (wd)); // w is how much we can copy... // adding in multiple of 4 because it's C... srcwidth = 4* pifSrc->pwidth; #endif while( LockedExchange( &lock, 1 ) ) Relinquish(); //Log8( WIDE("Do blot work...%d(%d),%d(%d) %d(%d) %d(%d)") // , ws, FROMFIXED(ws), hs, FROMFIXED(hs) // , wd, FROMFIXED(wd), hd, FROMFIXED(hd) ); if( ( pifDest->flags & IF_FLAG_FINAL_RENDER ) && !( pifDest->flags & IF_FLAG_IN_MEMORY ) ) { int updated = 0; Image topmost_parent; // closed loop to get the top imgae size. for( topmost_parent = pifSrc; topmost_parent->pParent; topmost_parent = topmost_parent->pParent ); ReloadOpenGlTexture( pifSrc, 0 ); if( !pifSrc->glActiveSurface ) { lprintf( WIDE( "gl texture hasn't downloaded or went away?" ) ); lock = 0; return; } //lprintf( WIDE( "use regular texture %p (%d,%d)" ), pifSrc, pifSrc->width, pifSrc->height ); { int glDepth = 1; VECTOR v1[2], v3[2], v4[2], v2[2]; int v = 0; double x_size, x_size2, y_size, y_size2; /* * only a portion of the image is actually used, the rest is filled with blank space * */ TranslateCoord( pifDest, &xd, &yd ); TranslateCoord( pifSrc, &xs, &ys ); v1[v][0] = xd; v1[v][1] = yd; v1[v][2] = 0.0; v2[v][0] = xd; v2[v][1] = yd+hd; v2[v][2] = 0.0; v3[v][0] = xd+wd; v3[v][1] = yd+hd; v3[v][2] = 0.0; v4[v][0] = xd+wd; v4[v][1] = yd; v4[v][2] = 0.0; x_size = (double) xs/ (double)topmost_parent->width; x_size2 = (double) (xs+ws)/ (double)topmost_parent->width; y_size = (double) ys/ (double)topmost_parent->height; y_size2 = (double) (ys+hs)/ (double)topmost_parent->height; while( pifDest && pifDest->pParent ) { glDepth = 0; if( pifDest->transform ) { Apply( pifDest->transform, v1[1-v], v1[v] ); Apply( pifDest->transform, v2[1-v], v2[v] ); Apply( pifDest->transform, v3[1-v], v3[v] ); Apply( pifDest->transform, v4[1-v], v4[v] ); v = 1-v; } pifDest = pifDest->pParent; } if( pifDest->transform ) { Apply( pifDest->transform, v1[1-v], v1[v] ); Apply( pifDest->transform, v2[1-v], v2[v] ); Apply( pifDest->transform, v3[1-v], v3[v] ); Apply( pifDest->transform, v4[1-v], v4[v] ); v = 1-v; } #if 0 if( glDepth ) { //lprintf( WIDE( "enqable depth..." ) ); glEnable( GL_DEPTH_TEST ); } else { //lprintf( WIDE( "disable depth..." ) ); glDisable( GL_DEPTH_TEST ); } #endif glBindTexture(GL_TEXTURE_2D, pifSrc->glActiveSurface); // Select Our Texture if( method == BLOT_COPY ) glColor4ub( 255,255,255,255 ); else if( method == BLOT_SHADED ) { CDATA tmp = va_arg( colors, CDATA ); glColor4ubv( (GLubyte*)&tmp ); } else if( method == BLOT_MULTISHADE ) { #if !defined( __ANDROID__ ) InitShader(); if( glUseProgram && l.glActiveSurface->shader.multi_shader ) { int err; CDATA r = va_arg( colors, CDATA ); CDATA g = va_arg( colors, CDATA ); CDATA b = va_arg( colors, CDATA ); glEnable(GL_FRAGMENT_PROGRAM_ARB); glUseProgram( l.glActiveSurface->shader.multi_shader ); err = glGetError(); glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 0, (float)GetRedValue( r )/255.0f, (float)GetGreenValue( r )/255.0f, (float)GetBlueValue( r )/255.0f, (float)GetAlphaValue( r )/255.0f ); err = glGetError(); glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 1, (float)GetRedValue( g )/255.0f, (float)GetGreenValue( g )/255.0f, (float)GetBlueValue( g )/255.0f, (float)GetAlphaValue( g )/255.0f ); err = glGetError(); glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 2, (float)GetRedValue( b )/255.0f, (float)GetGreenValue( b )/255.0f, (float)GetBlueValue( b )/255.0f, (float)GetAlphaValue( b )/255.0f ); err = glGetError(); } else #endif { Image output_image; CDATA r = va_arg( colors, CDATA ); CDATA g = va_arg( colors, CDATA ); CDATA b = va_arg( colors, CDATA ); output_image = GetShadedImage( pifSrc, r, g, b ); glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface ); glColor4ub( 255,255,255,255 ); } } else if( method == BLOT_INVERTED ) { #if !defined( __ANDROID__ ) InitShader(); if( l.glActiveSurface->shader.inverse_shader ) { int err; //lprintf( WIDE( "HAVE SHADER %d" ), l.glActiveSurface->shader.inverse_shader ); glEnable(GL_FRAGMENT_PROGRAM_ARB); glUseProgram( l.glActiveSurface->shader.inverse_shader ); err = glGetError(); } else #endif { Image output_image; //lprintf( WIDE( "DID NOT HAVE SHADER" ) ); output_image = GetInvertedImage( pifSrc ); glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface ); glColor4ub( 255,255,255,255 ); } } glBegin(GL_TRIANGLE_STRIP); //glBegin(GL_QUADS); // Front Face //glColor4ub( 255,120,32,192 ); scale( v1[v], v1[v], l.scale ); scale( v2[v], v2[v], l.scale ); scale( v3[v], v3[v], l.scale ); scale( v4[v], v4[v], l.scale ); glTexCoord2f(x_size, y_size); glVertex3fv(v1[v]); // Bottom Left Of The Texture and Quad glTexCoord2f(x_size, y_size2); glVertex3fv(v2[v]); // Bottom Right Of The Texture and Quad glTexCoord2f(x_size2, y_size); glVertex3fv(v4[v]); // Top Left Of The Texture and Quad glTexCoord2f(x_size2, y_size2); glVertex3fv(v3[v]); // Top Right Of The Texture and Quad // Back Face glEnd(); #if !defined( __ANDROID__ ) if( method == BLOT_MULTISHADE ) { if( l.glActiveSurface->shader.multi_shader ) { glDisable(GL_FRAGMENT_PROGRAM_ARB); } } else if( method == BLOT_INVERTED ) { if( l.glActiveSurface->shader.inverse_shader ) { glDisable(GL_FRAGMENT_PROGRAM_ARB); } } #endif glBindTexture(GL_TEXTURE_2D, 0); // Select Our Texture } } else switch( method ) { case BLOT_COPY: if( !nTransparent ) cBlotScaledT0( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth ); else if( nTransparent == 1 ) cBlotScaledT1( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth ); else if( nTransparent & ALPHA_TRANSPARENT ) cBlotScaledTImgA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF ); else if( nTransparent & ALPHA_TRANSPARENT_INVERT ) cBlotScaledTImgAI( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF ); else cBlotScaledTA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent ); break; case BLOT_SHADED: if( !nTransparent ) cBlotScaledShadedT0( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, va_arg( colors, CDATA ) ); else if( nTransparent == 1 ) cBlotScaledShadedT1( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, va_arg( colors, CDATA ) ); else if( nTransparent & ALPHA_TRANSPARENT ) cBlotScaledShadedTImgA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF, va_arg( colors, CDATA ) ); else if( nTransparent & ALPHA_TRANSPARENT_INVERT ) cBlotScaledShadedTImgAI( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF, va_arg( colors, CDATA ) ); else cBlotScaledShadedTA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent, va_arg( colors, CDATA ) ); break; case BLOT_MULTISHADE: { CDATA r,g,b; r = va_arg( colors, CDATA ); g = va_arg( colors, CDATA ); b = va_arg( colors, CDATA ); if( !nTransparent ) cBlotScaledMultiT0( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth , r, g, b ); else if( nTransparent == 1 ) cBlotScaledMultiT1( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth , r, g, b ); else if( nTransparent & ALPHA_TRANSPARENT ) cBlotScaledMultiTImgA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth , nTransparent & 0xFF , r, g, b ); else if( nTransparent & ALPHA_TRANSPARENT_INVERT ) cBlotScaledMultiTImgAI( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth , nTransparent & 0xFF , r, g, b ); else cBlotScaledMultiTA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth , nTransparent , r, g, b ); } break; } lock = 0; // Log( WIDE("Blot done") ); }
//////////////////////////////////////////////////////////////////////////////// //#include "../../../code/image_proc/image/hsi.hpp" bool CColorAdjustDialog::DrawPreview(CPaintDC& dc, RECT* rect) { if (!m_blit_tile || m_blit_tile->GetPixels() == NULL || rect == NULL) { return false; } ///////////////////////////////////////////////////////// const int width = m_blit_tile->GetWidth(); const int height = m_blit_tile->GetHeight(); int current_width = m_Width; if (current_width > width) current_width = width; int current_height = m_Height; if (current_height > height) current_height = height; BGRA* pixels = (BGRA*) m_blit_tile->GetPixels(); for (int iy = 0; iy < current_height; iy++) { for (int ix = 0; ix < current_width; ix++) { pixels[iy * width + ix].red = m_Pixels[iy * m_Width + ix].red; pixels[iy * width + ix].green = m_Pixels[iy * m_Width + ix].green; pixels[iy * width + ix].blue = m_Pixels[iy * m_Width + ix].blue; pixels[iy * width + ix].alpha = m_Pixels[iy * m_Width + ix].alpha; } } ///////////////////////////////////////////////////////// int red_value = GetRedValue(); int green_value = GetGreenValue(); int blue_value = GetBlueValue(); int alpha_value = GetAlphaValue(); int use_red = ShouldUseRedChannel(); int use_green = ShouldUseGreenChannel(); int use_blue = ShouldUseBlueChannel(); int use_alpha = ShouldUseAlphaChannel(); int method = 0; if (method == 0) { for (int iy = 0; iy < current_height; iy++) { for (int ix = 0; ix < current_width; ix++) { if (use_red) pixels[iy * width + ix].red += red_value; if (use_green) pixels[iy * width + ix].green += green_value; if (use_blue) pixels[iy * width + ix].blue += blue_value; if (use_alpha) pixels[iy * width + ix].alpha += alpha_value; } } } /* else { double h_value = ((double)red_value / (double)255.0) * ((double)2.0 * 3.14); double s_value = ((double)green_value / (double)255.0); double i_value = ((double)blue_value / (double)255.0); for (int iy = 0; iy < current_height; iy++) { for (int ix = 0; ix < current_width; ix++) { double r = pixels[iy * width + ix].red / 255.0; double g = pixels[iy * width + ix].green / 255.0; double b = pixels[iy * width + ix].blue / 255.0; double h, s, i; RGBtoHSI(r, g, b, &h, &s, &i); if (use_red) h += h_value; if (use_green) s += s_value; if (use_blue) i += i_value; if (use_alpha) pixels[iy * width + ix].alpha += alpha_value; HSItoRGB(h, s, i, &r, &g, &b); pixels[iy * width + ix].red = r * 255; pixels[iy * width + ix].green = g * 255; pixels[iy * width + ix].blue = b * 255; } } } */ ///////////////////////////////////////////////////////// dc.BitBlt(rect->left, rect->top, current_width, current_height, CDC::FromHandle(m_blit_tile->GetDC()), 0, 0, SRCCOPY); if (1) { rect->left += current_width; dc.FillRect(rect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); rect->left -= current_width; rect->top += current_height; dc.FillRect(rect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); rect->top -= current_height; } return true; }
//--------------------------------------------------------------------------- // x, y is position // xs, ys is starting position on source bitmap (x, y is upper left) + xs, ys ) // w, h is height and width of the image to use. // default behavior is to omit copying 0 pixels for transparency // overlays.... void BlotImageSizedEx ( ImageFile *pifDest, ImageFile *pifSrc , int32_t xd, int32_t yd , int32_t xs, int32_t ys , uint32_t ws, uint32_t hs , uint32_t nTransparent , uint32_t method , ... ) { #define BROKEN_CODE PCDATA po, pi; //int hd, wd; uint32_t oo, oi; // treated as an adder... it is unsigned by math, but still results correct offset? static uint32_t lock; va_list colors; va_start( colors, method ); if( nTransparent > ALPHA_TRANSPARENT_MAX ) return; if( !pifSrc || !pifSrc->image || !pifDest //|| !pifDest->image ) { // this will happen when mixing modes... lprintf( WIDE( "sanity check failed %p %p %p" ), pifSrc, pifDest, pifSrc?pifSrc->image:NULL ); return; } //lprintf( WIDE( "BlotImageSized %d,%d to %d,%d by %d,%d" ), xs, ys, xd, yd, ws, hs ); { IMAGE_RECTANGLE r1; IMAGE_RECTANGLE r2; IMAGE_RECTANGLE rs; IMAGE_RECTANGLE rd; int tmp; //IMAGE_RECTANGLE r3; r1.x = xd; r1.y = yd; r1.width = ws; r1.height = hs; r2.x = pifDest->eff_x; r2.y = pifDest->eff_y; tmp = (pifDest->eff_maxx - pifDest->eff_x) + 1; if( tmp < 0 ) r2.width = 0; else r2.width = (IMAGE_SIZE_COORDINATE)tmp; tmp = (pifDest->eff_maxy - pifDest->eff_y) + 1; if( tmp < 0 ) r2.height = 0; else r2.height = (IMAGE_SIZE_COORDINATE)tmp; if( !IntersectRectangle( &rd, &r1, &r2 ) ) { //lprintf( WIDE( "Images do not overlap. %d,%d %d,%d vs %d,%d %d,%d" ), r1.x,r1.y,r1.width,r1.height // , r2.x,r2.y,r2.width,r2.height); return; } //lprintf( WIDE( "Correcting coordinates by %d,%d" ) // , rd.x - xd // , rd.y - yd // ); xs += rd.x - xd; ys += rd.y - yd; tmp = rd.x - xd; if( tmp > 0 && (unsigned)tmp > ws ) ws = 0; else { if( tmp < 0 ) ws += (unsigned)-tmp; else ws -= (unsigned)tmp; } tmp = rd.y - yd; if( tmp > 0 && (unsigned)tmp > hs ) hs = 0; else { if( tmp < 0 ) hs += (unsigned)-tmp; else hs -= (unsigned)tmp; } //lprintf( WIDE( "Resulting dest is %d,%d %d,%d" ), rd.x,rd.y,rd.width,rd.height ); xd = rd.x; yd = rd.y; r1.x = xs; r1.y = ys; r1.width = ws; r1.height = hs; r2.x = pifSrc->eff_x; r2.y = pifSrc->eff_y; tmp = (pifSrc->eff_maxx - pifSrc->eff_x) + 1; if( tmp < 0 ) r2.width = 0; else r2.width = (IMAGE_SIZE_COORDINATE)tmp; tmp = (pifSrc->eff_maxy - pifSrc->eff_y) + 1; if( tmp < 0 ) r2.height = 0; else r2.height = (IMAGE_SIZE_COORDINATE)tmp; if( !IntersectRectangle( &rs, &r1, &r2 ) ) { lprintf( WIDE( "Desired Output does not overlap..." ) ); return; } //lprintf( WIDE( "Resulting dest is %d,%d %d,%d" ), rs.x,rs.y,rs.width,rs.height ); ws = rs.width<rd.width?rs.width:rd.width; hs = rs.height<rd.height?rs.height:rd.height; xs = rs.x; ys = rs.y; //lprintf( WIDE( "Resulting rect is %d,%d to %d,%d dim: %d,%d" ), rs.x, rs.y, rd.x, rd.y, rs.width, rs.height ); //lprintf( WIDE( "Resulting rect is %d,%d to %d,%d dim: %d,%d" ), xs, ys, xd, yd, ws, hs ); } //lprintf( WIDE(WIDE( "Doing image (%d,%d)-(%d,%d) (%d,%d)-(%d,%d)" )), xs, ys, ws, hs, xd, yd, wd, hd ); if( (int32_t)ws <= 0 || (int32_t)hs <= 0 /*|| (int32_t)wd <= 0 || (int32_t)hd <= 0 */ ) { lprintf( WIDE( "out of bounds" ) ); return; } #ifdef _INVERT_IMAGE // set pointer in to the starting x pixel // on the last line of the image to be copied //pi = IMG_ADDRESS( pifSrc, xs, ys ); //po = IMG_ADDRESS( pifDest, xd, yd ); pi = IMG_ADDRESS( pifSrc, xs, ys ); po = IMG_ADDRESS( pifDest, xd, yd ); //cpg 19 Jan 2007 2>c:\work\sack\src\imglib\blotdirect.c(492) : warning C4146: unary minus operator applied to unsigned type, result still unsigned //cpg 19 Jan 2007 2>c:\work\sack\src\imglib\blotdirect.c(493) : warning C4146: unary minus operator applied to unsigned type, result still unsigned oo = 4*-(int)(ws+pifDest->pwidth); // w is how much we can copy... oi = 4*-(int)(ws+pifSrc->pwidth); // adding remaining width... #else // set pointer in to the starting x pixel // on the first line of the image to be copied... pi = IMG_ADDRESS( pifSrc, xs, ys ); po = IMG_ADDRESS( pifDest, xd, yd ); oo = 4*(pifDest->pwidth - ws); // w is how much we can copy... oi = 4*(pifSrc->pwidth - ws); // adding remaining width... #endif //lprintf( WIDE("Doing image (%d,%d)-(%d,%d) (%d,%d)-(%d,%d)"), xs, ys, ws, hs, xd, yd, wd, hd ); //oo = 4*(pifDest->pwidth - ws); // w is how much we can copy... //oi = 4*(pifSrc->pwidth - ws); // adding remaining width... while( LockedExchange( &lock, 1 ) ) Relinquish(); if( ( pifDest->flags & IF_FLAG_FINAL_RENDER ) && !( pifDest->flags & IF_FLAG_IN_MEMORY ) ) { Image topmost_parent; ReloadOpenGlTexture( pifSrc, 0 ); if( !pifSrc->glActiveSurface ) { //lprintf( WIDE( "gl texture hasn't updated or went away?" ) ); lock = 0; return; } //lprintf( WIDE( "use regular texture %p (%d,%d)" ), pifSrc, pifSrc->width, pifSrc->height ); //DebugBreak(); g // closed loop to get the top imgae size. for( topmost_parent = pifSrc; topmost_parent->pParent; topmost_parent = topmost_parent->pParent ); /* * only a portion of the image is actually used, the rest is filled with blank space * */ TranslateCoord( pifDest, &xd, &yd ); TranslateCoord( pifSrc, &xs, &ys ); { int glDepth = 1; double x_size, x_size2, y_size, y_size2; VECTOR v1[2], v3[2],v4[2],v2[2]; int v = 0; v1[v][0] = xd; v1[v][1] = yd; v1[v][2] = 0.0; v2[v][0] = xd; v2[v][1] = yd+hs; v2[v][2] = 0.0; v3[v][0] = xd+ws; v3[v][1] = yd+hs; v3[v][2] = 0.0; v4[v][0] = xd+ws; v4[v][1] = yd; v4[v][2] = 0.0; x_size = (double) xs/ (double)topmost_parent->width; x_size2 = (double) (xs+ws)/ (double)topmost_parent->width; y_size = (double) ys/ (double)topmost_parent->height; y_size2 = (double) (ys+hs)/ (double)topmost_parent->height; // Front Face //glColor4ub( 255,120,32,192 ); //lprintf( WIDE( "Texture size is %g,%g to %g,%g" ), x_size, y_size, x_size2, y_size2 ); while( pifDest && pifDest->pParent ) { glDepth = 0; if( pifDest->transform ) { Apply( pifDest->transform, v1[1-v], v1[v] ); Apply( pifDest->transform, v2[1-v], v2[v] ); Apply( pifDest->transform, v3[1-v], v3[v] ); Apply( pifDest->transform, v4[1-v], v4[v] ); v = 1-v; } pifDest = pifDest->pParent; } if( pifDest->transform ) { Apply( pifDest->transform, v1[1-v], v1[v] ); Apply( pifDest->transform, v2[1-v], v2[v] ); Apply( pifDest->transform, v3[1-v], v3[v] ); Apply( pifDest->transform, v4[1-v], v4[v] ); v = 1-v; } #if 0 if( glDepth ) { //lprintf( WIDE( "enqable depth..." ) ); glEnable( GL_DEPTH_TEST ); } else { //lprintf( WIDE( "disable depth..." ) ); glDisable( GL_DEPTH_TEST ); } #endif glBindTexture(GL_TEXTURE_2D, pifSrc->glActiveSurface); // Select Our Texture if( method == BLOT_COPY ) glColor4ub( 255,255,255,255 ); else if( method == BLOT_SHADED ) { CDATA tmp = va_arg( colors, CDATA ); glColor4ubv( (GLubyte*)&tmp ); } else if( method == BLOT_MULTISHADE ) { #if !defined( __ANDROID__ ) InitShader(); if( glUseProgram && l.glActiveSurface->shader.multi_shader ) { int err; CDATA r = va_arg( colors, CDATA ); CDATA g = va_arg( colors, CDATA ); CDATA b = va_arg( colors, CDATA ); glEnable(GL_FRAGMENT_PROGRAM_ARB); glUseProgram( l.glActiveSurface->shader.multi_shader ); err = glGetError(); glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 0, (float)GetRedValue( r )/255.0f, (float)GetGreenValue( r )/255.0f, (float)GetBlueValue( r )/255.0f, (float)GetAlphaValue( r )/255.0f ); err = glGetError(); glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 1, (float)GetRedValue( g )/255.0f, (float)GetGreenValue( g )/255.0f, (float)GetBlueValue( g )/255.0f, (float)GetAlphaValue( g )/255.0f ); err = glGetError(); glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 2, (float)GetRedValue( b )/255.0f, (float)GetGreenValue( b )/255.0f, (float)GetBlueValue( b )/255.0f, (float)GetAlphaValue( b )/255.0f ); err = glGetError(); } else #endif { Image output_image; CDATA r = va_arg( colors, CDATA ); CDATA g = va_arg( colors, CDATA ); CDATA b = va_arg( colors, CDATA ); output_image = GetShadedImage( pifSrc, r, g, b ); glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface ); glColor4ub( 255,255,255,255 ); } } else if( method == BLOT_INVERTED ) { #if !defined( __ANDROID__ ) InitShader(); if( l.glActiveSurface->shader.inverse_shader ) { int err; glEnable(GL_FRAGMENT_PROGRAM_ARB); glUseProgram( l.glActiveSurface->shader.inverse_shader ); err = glGetError(); } else #endif { Image output_image; output_image = GetInvertedImage( pifSrc ); glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface ); glColor4ub( 255,255,255,255 ); } } glBegin(GL_TRIANGLE_STRIP); //glBegin(GL_QUADS); scale( v1[v], v1[v], l.scale ); scale( v2[v], v2[v], l.scale ); scale( v3[v], v3[v], l.scale ); scale( v4[v], v4[v], l.scale ); glTexCoord2f(x_size, y_size); glVertex3fv(v1[v]); // Bottom Left Of The Texture and Quad glTexCoord2f(x_size, y_size2); glVertex3fv(v2[v]); // Top Left Of The Texture and Quad glTexCoord2f(x_size2, y_size); glVertex3fv(v4[v]); // Bottom Right Of The Texture and Quad glTexCoord2f(x_size2, y_size2); glVertex3fv(v3[v]); // Top Right Of The Texture and Quad // Back Face glEnd(); #if !defined( __ANDROID__ ) if( method == BLOT_MULTISHADE ) { if( l.glActiveSurface->shader.multi_shader ) { glDisable(GL_FRAGMENT_PROGRAM_ARB); } } else if( method == BLOT_INVERTED ) { if( l.glActiveSurface->shader.inverse_shader ) { glDisable(GL_FRAGMENT_PROGRAM_ARB); } } #endif glBindTexture(GL_TEXTURE_2D, 0); // Select Our Texture } } else { switch( method ) { case BLOT_COPY: if( !nTransparent ) CopyPixelsT0( po, pi, oo, oi, ws, hs ); else if( nTransparent == 1 ) CopyPixelsT1( po, pi, oo, oi, ws, hs ); else if( nTransparent & ALPHA_TRANSPARENT ) CopyPixelsTImgA( po, pi, oo, oi, ws, hs, nTransparent & 0xFF); else if( nTransparent & ALPHA_TRANSPARENT_INVERT ) CopyPixelsTImgAI( po, pi, oo, oi, ws, hs, nTransparent & 0xFF ); else CopyPixelsTA( po, pi, oo, oi, ws, hs, nTransparent ); break; case BLOT_SHADED: if( !nTransparent ) CopyPixelsShadedT0( po, pi, oo, oi, ws, hs , va_arg( colors, CDATA ) ); else if( nTransparent == 1 ) CopyPixelsShadedT1( po, pi, oo, oi, ws, hs , va_arg( colors, CDATA ) ); else if( nTransparent & ALPHA_TRANSPARENT ) CopyPixelsShadedTImgA( po, pi, oo, oi, ws, hs, nTransparent & 0xFF , va_arg( colors, CDATA ) ); else if( nTransparent & ALPHA_TRANSPARENT_INVERT ) CopyPixelsShadedTImgAI( po, pi, oo, oi, ws, hs, nTransparent & 0xFF , va_arg( colors, CDATA ) ); else CopyPixelsShadedTA( po, pi, oo, oi, ws, hs, nTransparent , va_arg( colors, CDATA ) ); break; case BLOT_MULTISHADE: { CDATA r,g,b; r = va_arg( colors, CDATA ); g = va_arg( colors, CDATA ); b = va_arg( colors, CDATA ); //lprintf( WIDE( "r g b %08x %08x %08x" ), r,g, b ); if( !nTransparent ) CopyPixelsMultiT0( po, pi, oo, oi, ws, hs , r, g, b ); else if( nTransparent == 1 ) CopyPixelsMultiT1( po, pi, oo, oi, ws, hs , r, g, b ); else if( nTransparent & ALPHA_TRANSPARENT ) CopyPixelsMultiTImgA( po, pi, oo, oi, ws, hs, nTransparent & 0xFF , r, g, b ); else if( nTransparent & ALPHA_TRANSPARENT_INVERT ) CopyPixelsMultiTImgAI( po, pi, oo, oi, ws, hs, nTransparent & 0xFF , r, g, b ); else CopyPixelsMultiTA( po, pi, oo, oi, ws, hs, nTransparent , r, g, b ); } break; } MarkImageUpdated( pifDest ); } lock = 0; //lprintf( WIDE( "Image done.." ) ); }