2014-03-31 2 views
0

jpeg를 확대/축소하려면 다음 코드를 사용하고 있습니다. 인터넷의 예에서 ZoomOutJpeg() 함수가 있습니다. 저자는 내가 0.2 또는 2 (줌과 같은 다른 요인이 코드를 사용하는 경우 일이 무엇 "zoom out picture. the factor should between 0.5 and 1.0. It can be 0.5, but can not be 1.0." 말했다 왜jpeg 이미지 크기를 조정 하시겠습니까?

  1. 가 이해가 안 :

    //JpegLib Error Handing - Begin 
    struct my_error_mgr 
    { 
        struct jpeg_error_mgr pub; /* "public" fields */ 
    
        jmp_buf setjmp_buffer; /* for return to caller */ 
    }; 
    
    typedef struct my_error_mgr * my_error_ptr; 
    
    /* 
    * Here's the routine that will replace the standard error_exit method: 
    */ 
    
    METHODDEF(void) 
    my_error_exit(j_common_ptr cinfo) 
    { 
        /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ 
        my_error_ptr myerr = (my_error_ptr)cinfo->err; 
    
        /* Always display the message. */ 
        /* We could postpone this until after returning, if we chose. */ 
        (*cinfo->err->output_message) (cinfo); 
    
        /* Return control to the setjmp point */ 
        longjmp(myerr->setjmp_buffer, 1); 
    } 
    //JpegLib Error Handing - End 
    
    /* 
    * zoom out picture. the factor should between 0.5 and 1.0. It can be 0.5, but can not be 1.0. 
    */ 
    bool ZoomOutJpeg(UINT8 *inBuff, UINT8 *outBuff, UINT32 inSize, UINT32* _outSize, float factor) 
    { 
        //if (factor > 1 || factor < 0.5f) 
        // return false; 
    
        // init decompress struct 
        struct jpeg_decompress_struct in; 
        JSAMPROW inRowPointer[1]; 
        // init compress struct 
        struct jpeg_compress_struct out;  
        JSAMPROW outRowPointer[1]; 
        struct my_error_mgr jerrIn; 
        struct my_error_mgr jerrOut; 
    
        /* We set up the normal JPEG error routines, then override error_exit. */ 
        in.err = jpeg_std_error(&jerrIn.pub); 
        jerrIn.pub.error_exit = my_error_exit; 
        /* Establish the setjmp return context for my_error_exit to use. */ 
        if (setjmp(jerrIn.setjmp_buffer)) 
        { 
         jpeg_destroy_decompress(&in); 
         return false; 
        } 
        jpeg_create_decompress(&in); 
        jpeg_mem_src(&in, inBuff, inSize); 
        jpeg_read_header(&in, TRUE); 
        jpeg_start_decompress(&in); 
    
        out.err = jpeg_std_error(&jerrOut.pub); 
        jerrOut.pub.error_exit = my_error_exit; 
        /* Establish the setjmp return context for my_error_exit to use. */ 
        if (setjmp(jerrOut.setjmp_buffer)) 
        { 
         jpeg_destroy_decompress(&in); 
         jpeg_destroy_compress(&out); 
         return false; 
        } 
        jpeg_create_compress(&out); 
        jpeg_mem_dest(&out, &outBuff, (unsigned long*)_outSize); 
    
        int width = in.output_width; 
        int height = in.output_height; 
        int bytesPerPixel = in.num_components; 
    
        int destWidth = (int)(width * factor); 
        int destHeight = (int)(height * factor); 
        _outFrameSize->resX = destWidth; 
        _outFrameSize->resY = destHeight; 
    
        out.image_width = destWidth; 
        out.image_height = destHeight; 
        out.input_components = bytesPerPixel; 
        out.in_color_space = JCS_RGB; 
    
        jpeg_set_defaults(&out); 
        jpeg_start_compress(&out, TRUE); 
    
        // Process RGB data. 
        int outRowStride = destWidth * bytesPerPixel; 
        int inRowStride = width * bytesPerPixel; 
        outRowPointer[0] = (unsigned char *)malloc(outRowStride); 
        inRowPointer[0] = (unsigned char *)malloc(inRowStride); 
    
        JSAMPROW baseInRowPointer[1]; 
        baseInRowPointer[0] = (unsigned char *)malloc(inRowStride); 
    
        unsigned char bUpLeft, bUpRight, bDownLeft, bDownRight; 
        unsigned char gUpLeft, gUpRight, gDownLeft, gDownRight; 
        unsigned char rUpLeft, rUpRight, rDownLeft, rDownRight; 
        unsigned char b, g, r; 
    
        float fX, fY; 
        int iX, iY; 
        int i, j; 
    
        int currentBaseLocation = -1; 
        int count = 0; 
    
        // Process the first line. 
        jpeg_read_scanlines(&in, inRowPointer, 1); 
        for (j = 0; j < destWidth; j++) 
        { 
         fX = ((float)j)/factor; 
         iX = (int)fX; 
    
         bUpLeft = inRowPointer[0][iX * 3 + 0]; 
         bUpRight = inRowPointer[0][(iX + 1) * 3 + 0]; 
    
         gUpLeft = inRowPointer[0][iX * 3 + 1]; 
         gUpRight = inRowPointer[0][(iX + 1) * 3 + 1]; 
    
         rUpLeft = inRowPointer[0][iX * 3 + 2]; 
         rUpRight = inRowPointer[0][(iX + 1) * 3 + 2]; 
    
         b = bUpLeft * (iX + 1 - fX) + bUpRight * (fX - iX); 
         g = gUpLeft * (iX + 1 - fX) + gUpRight * (fX - iX); 
         r = rUpLeft * (iX + 1 - fX) + rUpRight * (fX - iX); 
    
         outRowPointer[0][j * 3 + 0] = b; 
         outRowPointer[0][j * 3 + 1] = g; 
         outRowPointer[0][j * 3 + 2] = r; 
        } 
        jpeg_write_scanlines(&out, outRowPointer, 1); 
    
        currentBaseLocation = 0; 
    
        //Process the other lines between the first and last. 
        for (i = 1; i < destHeight - 1; i++) 
        { 
         fY = ((float)i)/factor; 
         iY = (int)fY; 
    
         if (iY == currentBaseLocation) 
         { 
          in.output_scanline = iY; 
          SwapJsampRow(inRowPointer[0], baseInRowPointer[0]); 
          jpeg_read_scanlines(&in, baseInRowPointer, 1); 
         } 
         else 
         { 
          in.output_scanline = iY - 1; 
          jpeg_read_scanlines(&in, inRowPointer, 1); 
          jpeg_read_scanlines(&in, baseInRowPointer, 1); 
         } 
    
         currentBaseLocation = iY + 1; 
    
         for (j = 0; j < destWidth; j++) 
         { 
          fX = ((float)j)/factor; 
          iX = (int)fX; 
    
          bUpLeft = inRowPointer[0][iX * 3 + 0]; 
          bUpRight = inRowPointer[0][(iX + 1) * 3 + 0]; 
          bDownLeft = baseInRowPointer[0][iX * 3 + 0]; 
          bDownRight = baseInRowPointer[0][(iX + 1) * 3 + 0]; 
    
          gUpLeft = inRowPointer[0][iX * 3 + 1]; 
          gUpRight = inRowPointer[0][(iX + 1) * 3 + 1]; 
          gDownLeft = baseInRowPointer[0][iX * 3 + 1]; 
          gDownRight = baseInRowPointer[0][(iX + 1) * 3 + 1]; 
    
          rUpLeft = inRowPointer[0][iX * 3 + 2]; 
          rUpRight = inRowPointer[0][(iX + 1) * 3 + 2]; 
          rDownLeft = baseInRowPointer[0][iX * 3 + 2]; 
          rDownRight = baseInRowPointer[0][(iX + 1) * 3 + 2]; 
    
          b = bUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + bUpRight * (fX - iX) * (iY + 1 - fY) + bDownLeft * (iX + 1 - fX) * (fY - iY) + bDownRight * (fX - iX) * (fY - iY); 
          g = gUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + gUpRight * (fX - iX) * (iY + 1 - fY) + gDownLeft * (iX + 1 - fX) * (fY - iY) + gDownRight * (fX - iX) * (fY - iY); 
          r = rUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + rUpRight * (fX - iX) * (iY + 1 - fY) + rDownLeft * (iX + 1 - fX) * (fY - iY) + rDownRight * (fX - iX) * (fY - iY); 
    
          outRowPointer[0][j * 3 + 0] = b; 
          outRowPointer[0][j * 3 + 1] = g; 
          outRowPointer[0][j * 3 + 2] = r; 
         } 
    
         jpeg_write_scanlines(&out, outRowPointer, 1); 
        } 
    
        //Process the last line. 
        in.output_scanline = height - 1; 
        jpeg_read_scanlines(&in, inRowPointer, 1); 
        for (j = 0; j < destWidth; j++) 
        { 
         fX = ((float)j)/factor; 
         iX = (int)fX; 
    
         bUpLeft = inRowPointer[0][iX * 3 + 0]; 
         bUpRight = inRowPointer[0][(iX + 1) * 3 + 0]; 
    
         gUpLeft = inRowPointer[0][iX * 3 + 1]; 
         gUpRight = inRowPointer[0][(iX + 1) * 3 + 1]; 
    
         rUpLeft = inRowPointer[0][iX * 3 + 2]; 
         rUpRight = inRowPointer[0][(iX + 1) * 3 + 2]; 
    
         b = bUpLeft * (iX + 1 - fX) + bUpRight * (fX - iX); 
         g = gUpLeft * (iX + 1 - fX) + gUpRight * (fX - iX); 
         r = rUpLeft * (iX + 1 - fX) + rUpRight * (fX - iX); 
    
         outRowPointer[0][j * 3 + 0] = b; 
         outRowPointer[0][j * 3 + 1] = g; 
         outRowPointer[0][j * 3 + 2] = r; 
        } 
        jpeg_write_scanlines(&out, outRowPointer, 1); 
    
        //free memory 
        free(inRowPointer[0]); 
        free(baseInRowPointer[0]); 
        free(outRowPointer[0]); 
    
        // close resource 
        jpeg_finish_decompress(&in); 
        jpeg_destroy_decompress(&in); 
        jpeg_finish_compress(&out); 
        jpeg_destroy_compress(&out); 
    
        return true; 
    } 
    

    나는 위의 코드에 대한 몇 가지 질문이)?

  2. 아래와 같은 오류가 발생하여 jpeg_destroy_decompress(&in); jpeg_destroy_compress(&out);을 사용할 때 잠재적 인 문제가 있습니까?

  3. ZoomOutJpeg()의 인자를 0.23으로 사용하면 종종 오류가 발생하고 결과 이미지가 손상됩니다. 어떻게 해결할 수 있을까요, 저는 어떤 요인으로도 Scale에 정말로 가고 싶습니다.

  4. 마지막으로 누군가가 다른 알고리즘이나 jpeg를 확장 할 라이브러리가 있으면 성능이 가장 좋습니다. 나를 소개해주십시오.

대단히 감사합니다.

& T T

+1

'jmp_buf setjmp_buffer;'. 그것은 충분히 알려줍니다. 이것은 좋은 코드가 아닙니다. – MSalters

답변

0
  1. 출력 화소 값이 가장 × 2 입력에 이웃에 기초한다. 이는 자동으로 축척 계수가 1/2로 제한된다는 것을 의미합니다. 1보다 큰 스케일 인수에는 보간이 필요하지만이 코드에서는 수행하지 않습니다.
  2. 오류 처리 및 정리 유형은 매우 약합니다. RAII 만 사용하십시오.
  3. 0.23으로 스케일링하려면 출력 코드 당 5x5 입력 픽셀이 필요합니다.이 코드에서는 수행 할 수 없습니다.
  4. 라이브러리 요청이 SO에서 주제와 관련이 없으므로 검색 엔진 만 사용하십시오.
+0

감사합니다! 내 다른 질문을 참조하십시오 http://stackoverflow.com/questions/22859843/image-is-damaged-when-using-jpegbitmapencoder – TTGroup

관련 문제