Guest User

Untitled

a guest
Apr 20th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.50 KB | None | 0 0
  1. // MMXSurface32.cpp : implementation of the CMMXSurface32Intrinsic
  2. // class
  3. //
  4. // This is a part of the Microsoft Foundation Classes C++ library.
  5. // Copyright (c) Microsoft Corporation.  All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. //
  13. #include "stdafx.h"
  14. #include "MMXSurface.h"
  15. #include "MMXWrapper.h"
  16.  
  17. typedef CMMXUnsigned16Saturated CMMX;
  18.  
  19. // Optimized for a 2-pixel processing 32 bit buffer
  20. void CMMXSurface32Intrinsic::AdjustWidth(int *pWidth)
  21. {
  22.     ASSERT(pWidth != NULL);
  23.     ASSERT(m_kDeltaX == 1);
  24.     // increment if odd.  If we are even, we stop
  25.     // dead on correctly, reading the single black buffer
  26.     // column. If we are odd, we need an extra column so
  27.     // we don't need to special case the tail of the loop.
  28.  
  29.     // Because we know there is always a DeltaX black stripe
  30.     // at least 1 pixel wide, we can subtract instead of adding.
  31.     // this allows us to get rid of adding a delta per horizontal
  32.     // loop. while in theory this could cause the left side to bleed
  33.     // to the right, in reality this won't happen.
  34.     if (*pWidth & 0x01)
  35.         *pWidth -= 1;
  36. }
  37.  
  38. void CMMXSurface32Intrinsic::OnCreated()
  39. {
  40.     ASSERT(GetBitDepth() == 32);
  41.     ASSERT((GetPitch() & 0x7) == 0);
  42.     ASSERT(GetVisibleWidth() && GetVisibleHeight());
  43.  
  44.     int width = GetVisibleWidth();
  45.     m_dwpl = GetPitch()/4; // dwords Per Line
  46.     m_width = (width+1)/2; // 2 pixels at a time
  47. }
  48.  
  49. void CMMXSurface32Intrinsic::BlurBits()
  50. {
  51.     int height = GetVisibleHeight();
  52.     DWORD *pCur  = (DWORD *)GetPixelAddress(0,0);
  53.  
  54.     CMMX cFader;
  55.     CMMX cRight, cRightRight;
  56.     CMMX cDownRight;
  57.     CMMX cLeft;
  58.     CMMX cUpRight;
  59.     CMMX cUp, cDown, cCur;
  60.  
  61.     cFader.UnpackBytesLo( 0x01010101 );
  62.     cLeft.Clear();
  63.     cCur.UnpackBytesLo( *pCur );
  64.  
  65.     do {
  66.         int width = m_width;
  67.         do {
  68.             // Load pixels and do the mmx unpack
  69.             cRight.UnpackBytesLo( pCur[1] );
  70.             cRightRight.UnpackBytesLo( pCur[2] );
  71.             cUp.UnpackBytesLo( pCur[-m_dwpl] );
  72.             cUpRight.UnpackBytesLo( pCur[-m_dwpl+1] );
  73.             cDown.UnpackBytesLo( pCur[m_dwpl] );
  74.             cDownRight.UnpackBytesLo( pCur[m_dwpl+1] );
  75.  
  76.             // Actual math. Don't step on current, or right.
  77.             // Sum the 4 around and double the middle
  78.  
  79.             // Do current pixel in this line
  80.             cUp = (cDown+cUp+cLeft+cRight+(cCur<<2))>>3;
  81.  
  82.             // Do next pixel
  83.             cDown = (cDownRight+cUpRight+cCur+cRightRight+(cRight<<2))>>3;
  84.  
  85. #if defined(TRIPPY)
  86.             cUp += cFader; // increase the fade to white
  87.             cDown += cFader; // increase the fade to white
  88. #elif defined (FAST_FADE)
  89.             cUp -= cFader; // increase the fade to black
  90.             cDown -= cFader; // increase the fade to black
  91. #endif
  92.             cLeft = cRight;         // Slide left!
  93.             cCur = cRightRight;
  94.  
  95.             *(ULONGLONG *)pCur = cUp.PackBytes(cDown);
  96.             pCur += 2;
  97.         } while (--width > 0);
  98.     } while (--height > 0);
  99. }
  100.  
  101. //Grupo 4
  102. void CMMXSurface32Intrinsic::GrayScale()
  103. {
  104.     int height = GetVisibleHeight()*2;  //altura multiplicada por 2 pois são pixels de 32 bits em variáveis de64 bits (2x maior)
  105.     DWORD *pCur  = (DWORD *)GetPixelAddress(0,0);   // cada pixel tem 32bits, 1byte para cada canal de cor: alfa, red, green, blue
  106.  
  107.     // Variaveis do tipo unsigned long long, de 64 bits
  108.     ULONGLONG mascara = 0xFF;   //seleciona um byte de alguma variável (utilizada para pegar valores individuais de RGB)  
  109.     ULONGLONG pixel;    //recebe os valores referentes a um ponto da tela
  110.     ULONGLONG next;     //recebe os valores do próximo ponto a partir de pixel
  111.    
  112.     pixel = *(ULONGLONG *)pCur; //faz um casting 64 bits dos dados do ponto atual na variável pixel
  113.    
  114.     //loops para percorrer toda a tela
  115.     do {
  116.         int width = m_width;
  117.         do {
  118.            
  119.             next = *(ULONGLONG *)(pCur+1);  //próximo ponto recebe o ponteiro que aponta para um ponto na tela + 1
  120.            
  121.             //utilização dos registradores mmx 64 bits com inline assembly
  122.             __asm{
  123.                 movq mm0, pixel     //registrador mm0 reebe o valor do pixel atual
  124.                 pand mm0, mascara   //valor de mm0 recebe uma mascara para selecionar seu 1 byte menos significativo (B)
  125.                 movq mm1, mm0       //guarda o valor calculado acima em mm1
  126.                 movq mm0, pixel     //recarrega o valor do pixel em mm0
  127.                 psrlq mm0, 8        //realiza um shift lógico para a direita para pegar o próximo byte
  128.                 pand mm0, mascara   //utilizar mascara para isolar um byte (G)
  129.                 paddd mm1, mm0      //soma o valor calculado anteriormente em mm1 (B+G)
  130.                 movq mm0, pixel     //recarrega o valor do pixel em mm0
  131.                 psrlq mm0, 16       //realiza um shift lógico para direita para pegar o 3 byte
  132.                 pand mm0, mascara   //utiliza mascara para isolar um byte (R)
  133.                 paddd mm1,mm0       //soma o valor calculado acima em mm1 (B+G+R)
  134.                 movq pixel, mm1     //move para a variável pixel a soma dos valores RGB calculados nos registradores mmx
  135.             }
  136.  
  137.             pixel /= 3;             //realiza media dos valores RGB ((R+G+B)/3)
  138.  
  139.             __asm{
  140.                 movq mm0, pixel     //mm0 recebe a media dos valores RGB
  141.                 movq mm1, mm0       //copia mm0 em mm1
  142.                 psllq mm0, 8        //realiza um shift lógico para esquerda em 1 byte
  143.                 paddd mm1, mm0      //soma a (media<<8) em mm1
  144.                 psllq mm0, 8        //novamente um shift para esquerda em 1 byte
  145.                 paddd mm1, mm0      //soma a (media<<16) em mm1
  146.                 movq pixel, mm1     //mm1 agora possui os valores médios RGB (GrayScale), então salva isso em pixel
  147.             }
  148.  
  149.             *(ULONGLONG *)pCur = pixel;     //joga o resultado no ponto apontado da tela
  150.             pixel = next;                   //recebe o próximo pixel a ser processado
  151.             pCur++;                         //avança o ponteiro sobre a tela
  152.         } while (--width > 0);
  153.     } while (--height > 0);
  154. }
  155.  
  156. // Grupo5
  157. void CMMXSurface32Intrinsic::Sobel() {
  158.     CMMX cCur;
  159.     //ULONGLONG *pCur  = (ULONGLONG *)GetPixelAddress(0,0);
  160.  
  161.     sumX = 0;
  162.     sumY = 0;
  163.     SUM = 0;
  164.     //WORD *pwCur = (WORD *)pCur;
  165.     //Percorre toda imagem
  166.     for (y = 0; y < GetVisibleHeight(); y++) {
  167.         for (x = 0; x < GetVisibleWidth(); x++) {
  168.             sumX = 0;
  169.             sumY = 0;
  170.  
  171.             //Se for boada, atribui o valor 0(preto)
  172.             if((y==0) || (y == (GetVisibleHeight() - 1))){
  173.                 SUM = 0;
  174.             }
  175.             else {
  176.                 if((x==0) || (x == (GetVisibleWidth() - 1))){
  177.                     SUM = 0;
  178.                 }
  179.                 else
  180.                 {
  181.  
  182.                     for(I=-1; I<=1; I++)  {
  183.                         for(J=-1; J<=1; J++)  {
  184.  
  185.                             piX = J + x;
  186.                             piY = I + y;
  187.  
  188.                             //Pega o valor da imagem corrente
  189.                             cCur = PointColor(piX,piY);
  190.  
  191.                             r = GetRValue(cCur);
  192.                             g = GetGValue(cCur);
  193.                             b = GetBValue(cCur);
  194.  
  195.                             NC = (r+g+b)/3;
  196.  
  197.                             sumX = sumX + (NC) * GXS[J+1][I+1];
  198.                             sumY = sumY + (NC) * GYS[J+1][I+1];
  199.                         }
  200.                     }
  201.  
  202.                     SUM = abs(sumX) + abs(sumY);
  203.                 }
  204.             }
  205.  
  206.             if(SUM>255)
  207.                 SUM=255;
  208.             if(SUM<0)
  209.                 SUM=0;
  210.             newPixel = (255-(unsigned char)(SUM));
  211.            
  212.             PointColorT(x,y,RGB(newPixel,newPixel,newPixel));
  213.         }
  214.     }
  215.  
  216.     //Quando terminar, copia o resultado para a imagem corrente
  217.     Copy(t_image);
  218. }
  219.  
  220.  
  221.  
  222. // GRUPO 9 - Filtro Posterize
  223. //sobrescreve o Posterize do Surface
  224. void CMMXSurface32Intrinsic::Posterize()
  225. {
  226.     int height = GetVisibleHeight();
  227.     DWORD *pCur  = (DWORD *)GetPixelAddress(0,0);   // cada pixel tem 32bits, 1byte para cada canal de cor: alfa, red, green, blue
  228.  
  229.     // Variaveis do tipo unsigned long long, de 64 bits
  230.     ULONGLONG mascara = 0xC0C0C0C0C0C0C0C0;     //0xC = 1100, preservar dois MSD de cada byte.
  231.     ULONGLONG pixel;
  232.  
  233.     /* Iteracao principal, processa 2 pixeis em cada iteracao */
  234.     do {
  235.         int width = m_width;
  236.         do {
  237.             pixel = *(ULONGLONG *)pCur;
  238.             // inline assembly
  239.             __asm{
  240.                 movq mm0, pixel;    // ler pixeis atuais para registrador
  241.                 pand mm0, mascara   // aplicar mascara para descardar bits menos significativos
  242.                 movq pixel, mm0;
  243.             }
  244.             *(ULONGLONG *)pCur = pixel;
  245.             pCur+= 2;
  246.         } while (--width > 0);
  247.     } while (--height > 0);
  248. }
  249.  
  250. // Grupo 12 - Gray Filter
  251. void CMMXSurface32Intrinsic::GrayFilter(){
  252.  
  253.     int height = GetVisibleHeight()*2;  //altura multiplicada por 2 pois são pixels de 32 bits em variáveis de64 bits (2x maior)
  254.     DWORD *pCur  = (DWORD *)GetPixelAddress(0,0);   // cada pixel tem 32bits, 1byte para cada canal de cor: alfa, red, green, blue
  255.  
  256.     // Variaveis do tipo unsigned long long, de 64 bits
  257.     ULONGLONG mascara = 0xFF;   //seleciona um byte de alguma variável (utilizada para pegar valores individuais de RGB)
  258.     unsigned char whitePixel = 255;
  259.     ULONGLONG pixel;    //recebe os valores referentes a um ponto da tela
  260.     ULONGLONG next;     //recebe os valores do próximo ponto a partir de pixel
  261.    
  262.     pixel = *(ULONGLONG *)pCur; //faz um casting 64 bits dos dados do ponto atual na variável pixel
  263.    
  264.     //loops para percorrer toda a tela
  265.     do {
  266.         int width = m_width;
  267.         do {
  268.            
  269.             next = *(ULONGLONG *)(pCur+1);  //próximo ponto recebe o ponteiro que aponta para um ponto na tela + 1
  270.            
  271.             //utilização dos registradores mmx 64 bits com inline assembly
  272.             __asm{
  273.                 movq mm0, pixel     //registrador mm0 recebe o valor do pixel atual
  274.                 pand mm0, mascara   //valor de mm0 recebe uma mascara para selecionar seu 1 byte menos significativo (B)
  275.                 paddd mm0, whitePixel //acresce 255 a B
  276.                 psrlq mm0, 1        //1 shift para a direita (divide por 2, sem precisão)
  277.  
  278.                 movq mm1, pixel     //registrador mm1 recebe o valor do pixel atual
  279.                 psrlq mm1, 8        //realiza um shift lógico para direita para pegar o 2 byte
  280.                 pand mm1, mascara   //valor de mm1 recebe uma mascara para selecionar seu 2 byte menos significativo (G)
  281.                 paddd mm1, whitePixel //acresce 255 a G
  282.                 psrlq mm1, 1        //1 shift para a direita (divide por 2, sem precisão)
  283.  
  284.                 movq mm2, pixel     //registrador mm2 recebe o valor do pixel atual
  285.                 psrlq mm2, 16       //realiza um shift lógico para direita para pegar o 3 byte
  286.                 pand mm2, mascara   //valor de mm2 recebe uma mascara para selecionar seu 1 byte menos significativo (R)
  287.                 paddd mm2, whitePixel //acresce 255 a R
  288.                 psrlq mm2, 1        //1 shift para a direita (divide por 2, sem precisão)
  289.  
  290.                 pxor mm3, mm3       //garante que o registrador mm3 esta vazio
  291.                 paddd mm3, mm2      //copia o canal R (mm2) para mm3
  292.                 psllq mm0, 8        //um shift para esquerda em 1 byte
  293.                 paddd mm3, mm1      //copia o canal G (mm1) para mm3
  294.                 psllq mm0, 8        //novamente um shift para esquerda em 1 byte
  295.                 paddd mm3, mm0      //copia o canal B (mm0) para mm3
  296.  
  297.                 movq pixel, mm3     //retorna para a variavel alto nivel os novos valores do pixel
  298.             }
  299.  
  300.             *(ULONGLONG *)pCur = pixel;     //joga o resultado no ponto apontado da tela
  301.             pixel = next;                   //recebe o próximo pixel a ser processado
  302.             pCur++;                         //avança o ponteiro sobre a tela
  303.         } while (--width > 0);
  304.     } while (--height > 0);
  305. }
Add Comment
Please, Sign In to add comment