Greyscale JPEG zu YCbCr JPEG



  • Kann vermutlich jedes Bildbearbeitungsprogram das überhaupt JPEGs lesen und schreiben kann. Aber sicher nicht jedes kann es verlustfrei.

    War jetzt nicht gefordert, aber wäre ja nett. Zumal es mMn. relativ easy gehen muss.



  • Nene das ist mir schon klar, das funktioniert auch mit Paint. 😃

    Das Problem ist ich muss es selber programmieren, deswegen frage ich auch in diesem Forum nach.

    Der Ansatz das nur ein Kanal vorhanden ist und bei dem YCbCr Bild jeweils drei und zwei auf "Null" gesetzt werden sollen ist mir verständlich. Auch den Aufbau eines JPEGs mit Markern etz. verstehe ich.

    Aber ich kriegs einfach nicht hin es so hin zu "Hexen" das es korrekt ein 3 Kanal YCbCr Bild wird.

    Für Hilfe wäre ich sehr dankbar!

    Danke!



  • Tada12 schrieb:

    Aber ich kriegs einfach nicht hin es so hin zu "Hexen" das es korrekt ein 3 Kanal YCbCr Bild wird.

    Für Hilfe wäre ich sehr dankbar!

    Danke!

    Scherz?

    Ich meine ... was erwartest du jetzt?
    Du stellst keine konkrete Frage, also wird auch keine Antwort kommen.



  • Naja ich will wissen wie ich die einzelnen Marker eines greyscale JPEGs bearbeiten muss damit es zu einem 3 Kanal Jpeg wird.

    Gruß



  • Lies es dir aus der Doku/dem Standard raus. Das wird dir wohl keiner abnehmen. Wenn nicht zufällig jemand vorbeikommt der es weiss weil er sowas in der Art selbst schonmal gemacht hat...

    Vor allem da das ganze sehr verdächtig nach Hausaufgabe riecht.

    Wenn du beim Verständnis des Standards, bestimmter Formulierungen etc. Probleme hast kannst du ja nochmal nachfragen. Das wäre dann das was ich mit "konkreter Frage" gemeint habe.



  • Naja wenn das im Standard drinstehen würde :/.

    Also ich habe bereits so ziemlich alles probiert was mir eingefallen ist. Ich habe die SOF Marker um zwei Kanäle erweitert zusätzliche Qauntisierungs und Huffmann Tabellen für die fehlenden Kanäle eingefügt. Aber irgendwie funktioniert das einfach nicht!

    Ps. sind keine "Hausaufgaben". Ich habe einen RTP Streamer geschrieben, der Standard unterstütz aber leider nur 420 o. 422 YCbCr JPEGs fürs Streaming.



  • Tada12 schrieb:

    Naja wenn das im Standard drinstehen würde :/.

    Du hast A.
    Du willst B.
    Du hast die vollständige Dokumentation zum Aufbau von A und B.
    Ich sehe das Problem nicht.


  • Mod

    Tada12 schrieb:

    Naja wenn das im Standard drinstehen würde :/.

    im standard steht nicht wie das format richtig aufgebaut werden muss?



  • Hallo,

    wenn du das jpg geladen hast, hast dz zugriff auf die Pixelmap
    die ist immer 24 bit RGB bei JPG Files.

    Wie Du auf die Pixeldaten kommst weißt Du ja.

    Dann kannst Du in jedes beliebige Format Konvertieren wenn
    du zb eine externe lib verwendest "saveAs" oder selber die Pixel
    transformierst :

    Beispiel:

    ////////////////////////////////////////////////////////////////////////////////
    // Convert raw mode with 16 bit values pattern RG GB.
    ////////////////////////////////////////////////////////////////////////////////
    
    void CPicConvert::RawY16RGGB(DWORD XSize,DWORD YSize,BYTE *pBuf,BYTE *pBGR)
    {
      WORD *pR,*pB,*pG0,*pG1;
      DWORD i,j;
      WORD *pMem;
      struct pdst
      {
        BYTE B;
        BYTE G;
        BYTE R;
      }*pDst;
    
      pDst=(struct pdst*)pBGR;
      pMem=(WORD*)pBuf;
    
      for(i=0;i<YSize-1;i++)
      {
        if(i&1)
        {
          pG1=pMem+i*XSize;
          pB=pG1+1;
          pR=pG1+XSize;
          pG0=pR+1;
        }
        else
        {
          pR=pMem+i*XSize;
          pG0=pR+1;
          pG1=pR+XSize;
          pB=pG1+1;
        }
    
        // Go through all pixels
        for(j=0;j<XSize-1;j++)
        {
          // We only use one byte
          pDst->B=(BYTE)(*(BYTE*)pB);
          pDst->G=(BYTE)(((*(BYTE*)pG0+*(BYTE*)pG1)/2));
          pDst->R=(BYTE)(*(BYTE*)pR);
    
          pDst++;
    
          if(j&1)
          {
            pB+=2;
            pG0+=2;
          }
          else
          {
            pR+=2;
            pG1+=2;
          }
        }
        pDst->B=0;
        pDst->G=0;
        pDst->R=0;
    
        pDst++;
      }
    
      memset(pBGR+(XSize*(YSize-1))*3,0,XSize*3);
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    // Convert raw mode with 16 bit values pattern GR BG.
    ////////////////////////////////////////////////////////////////////////////////
    
    void CPicConvert::RawY16GRBG(DWORD XSize,DWORD YSize,BYTE *pBuf,BYTE *pBGR)
    {
      WORD *pR,*pB,*pG0,*pG1;
      DWORD i,j;
      WORD *pMem;
      struct pdst
      {
        BYTE B;
        BYTE G;
        BYTE R;
      }*pDst;
    
      pDst=(struct pdst*)pBGR;
      pMem=(WORD*)pBuf;
    
      for(i=0;i<YSize-1;i++)
      {
        if(i&1)
        {
          pB=pMem+i*XSize;
          pG1=pB+1;
          pG0=pB+XSize;
          pR=pG0+1;
        }
        else
        {
          pG0=pMem+i*XSize;
          pR=pG0+1;
          pB=pG0+XSize;
          pG1=pB+1;
        }
    
        // Go through all pixels
        for(j=0;j<XSize-1;j++)
        {
          // We only use one MSB (it the lower one)
          pDst->B=(BYTE)(*(BYTE*)pB);
          pDst->G=(BYTE)(((*(BYTE*)pG0+*(BYTE*)pG1)/2));
          pDst->R=(BYTE)(*(BYTE*)pR);
    
          pDst++;
    
          if(j&1)
          {
            pR+=2;
            pG1+=2;
          }
          else
          {
            pG0+=2;
            pB+=2;
          }
        }
    
        pDst->B=0;
        pDst->G=0;
        pDst->R=0;
    
        pDst++;
      }
    
      memset(pBGR+(XSize*(YSize-1))*3,0,XSize*3);
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    // Convert raw mode with 16 bit values pattern BG GR.
    ////////////////////////////////////////////////////////////////////////////////
    
    void CPicConvert::RawY16BGGR(DWORD XSize,DWORD YSize,BYTE *pBuf,BYTE *pBGR)
    {
      WORD *pR,*pB,*pG0,*pG1;
      DWORD i,j;
      WORD *pMem;
      struct pdst
      {
        BYTE B;
        BYTE G;
        BYTE R;
      }*pDst;
    
      pDst=(struct pdst*)pBGR;
      pMem=(WORD*)pBuf;
    
      for(i=0;i<YSize-1;i++)
      {
        if(i&1)
        {
          pG1=pMem+i*XSize;
          pR=pG1+1;
          pB=pG1+XSize;
          pG0=pB+1;
        }
        else
        {
          pB=pMem+i*XSize;
          pG0=pB+1;
          pG1=pB+XSize;
          pR=pG1+1;
        }
    
        // Go through all pixels
        for(j=0;j<XSize-1;j++)
        {
          // We only use one MSB (it the lower one)
          pDst->B=(BYTE)(*(BYTE*)pB);
          pDst->G=(BYTE)(((*(BYTE*)pG0+*(BYTE*)pG1)/2));
          pDst->R=(BYTE)(*(BYTE*)pR);
    
          pDst++;
    
          if(j&1)
          {
            pG0+=2;
            pR+=2;
          }
          else
          {
            pB+=2;
            pG1+=2;
          }
        }
        pDst->B=0;
        pDst->G=0;
        pDst->R=0;
    
        pDst++;
      }
    
      memset(pBGR+(XSize*(YSize-1))*3,0,XSize*3);
    }
    

    Ich mache das in Assembler nur so erlange ich den Datendurchsatz

    void CPicConvert::Y444(DWORD XSize,DWORD YSize,BYTE *pBuf,BYTE *pBGR)
    {
      DWORD  Cnt;
    
      Cnt=(XSize*YSize);
    
    #ifdef __SC__
      asm
    #else
      __asm
    #endif
      {
            mov     edx,Cnt
    
            mov     esi,pBuf
            mov     edi,pBGR
    
    lbl0:   movzx   eax,byte ptr [esi]              // Get U
            mov     eax,DWORD ptr UTable[eax*4]     // Load Ub and Ug
    
            movzx   ebx,byte ptr 2[esi]             // Get V
            mov     ebx,DWORD ptr VTable[ebx*4]     // Load Vr and Vg
    
            add     ax,bx                           // Build -0.3457U -0.7144V in ax
    
            movzx   cx,byte ptr 1[esi]              // Get Y0
    
            add     cx,ax                           // Build G0
            or      ch,ch
            je      lbl1
            mov     cl,ch
            neg     cl
    lbl1:   mov     1[edi],cl                       // Store G0
    
            shr     eax,16                          // Put Ub to AX
            shr     ebx,16                          // Put Vr to bx
    
            movzx   cx,byte ptr 1[esi]              // Get Y0
            add     cx,ax
            or      ch,ch
            je      lbl3
            mov     cl,ch
            neg     cl
    lbl3:   mov     [edi],cl                        // Store B0
    
            movzx   cx,byte ptr 1[esi]              // Get Y0
            add     cx,bx
            or      ch,ch
            je      lbl5
            mov     cl,ch
            neg     cl
    lbl5:   mov     2[edi],cl                       // Store R0
    
            add     esi,3
            add     edi,3
    
            dec     edx
            jnz     lbl0
      }
    }
    

    Und so weiter.. es gibt zig Converter ggf. anpassen.

    Gruß Karsten



  • @KahnSoft
    Du hast leider nicht im geringsten verstanden worum es geht.



  • Geistesblitze bleiben ein Mysterium, der eine Leitet sie ab, der andere weiter.



  • Was für Geistelblitze?
    Deine Antwort ist 100% unpassend.
    Eher geistiger Durchfall.



  • Verstehe ich nicht, man lädt ein 8 bit jpg, und wandelt es dann in ein Y Format um, dann kann man diese raw Daten stremen mache ich ständig so.

    Du bist ja ein richtiger MotzFoz, Freundlichkeit ist wichtiger wie dein Durchfall geschwafel


Anmelden zum Antworten