2012-05-06 2 views
0

libjpeg를 사용하여 스크린 샷을 opengl 버퍼에서 저장하려고합니다.메시지없이 죽는 libjpeg

내가 사용하는 기능은이 기능이 시작이 하나

void OnKeyPress(unsigned char key, int x, int y) { 
    if (key != static_cast<unsigned char>('p')) 
    return; 

    int width = g_current_width; 
    int height = g_current_height; 
    boost::scoped_array<boost::uint8_t> buffer(new boost::uint8_t[3 * width * height]); 

    glReadBuffer(GL_FRONT); 
    glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, 
       reinterpret_cast<GLvoid *>(buffer.get())); 
    glReadBuffer(GL_BACK); 

    FlipImage(buffer.get(), width, height); 

    // Generate a BMP files for testing purposes 
    SaveRGB("screenshot.bmp", buffer.get(), width, height); 

    boost::shared_ptr<FILE> outfile(fopen("screenshot.jpeg", "wb"), fclose); 
    if (!outfile) 
    return; 

    jpeg_compress_struct cinfo; 
    jpeg_error_mgr jerr; 
    cinfo.err = jpeg_std_error(&jerr); 
    jerr.trace_level = 10; 
    jpeg_create_compress(&cinfo); 
    jpeg_stdio_dest(&cinfo, outfile.get()); 

    cinfo.image_width = width; 
    cinfo.image_height = height; 
    cinfo.input_components = 3; 
    cinfo.in_color_space = JCS_RGB; 
    jpeg_set_defaults(&cinfo); 

    jpeg_set_quality(&cinfo, 100, true); 
    jpeg_start_compress(&cinfo, true); 
    int row_stride = width * 3; 
    JSAMPROW row_pointer[1]; 
    int counter = 0; 
    std::cout << boost::format("height: %d\n") % height; 
    boost::uint8_t *r_buffer = buffer.get(); 
    while (cinfo.next_scanline < cinfo.image_height) { 
    row_pointer[0] = &r_buffer[cinfo.next_scanline * row_stride]; 
    jpeg_write_scanlines(&cinfo, row_pointer, 1); 
    std::cout << boost::format("current line: %d\n") % (counter++); 
    } 
    jpeg_finish_compress(&cinfo); // never reaches this point 
    outfile.reset(); 
    jpeg_destroy_compress(&cinfo); 
} 

이지만, 약간의 반복 (약 100-150) 후 파일에 아무것도 작성 않으며, 경고 또는 오류를 생성하지 않고 함수가 반환.

메모리 인코딩을 사용하면 (실제로 필요한 기능 임) 함수가 완료되지만 결과가 의미가 없습니다. 또한, 버퍼를 해제하려는 시도는 오류로 끝납니다. 여기

void OnKeyPress(unsigned char key, int x, int y) { 
    if (key != static_cast<unsigned char>('p')) 
    return; 

    int width = g_current_width; 
    int height = g_current_height; 
    boost::scoped_array<boost::uint8_t> buffer(new boost::uint8_t[3 * width * height]); 

    glReadBuffer(GL_FRONT); 
    glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, 
       reinterpret_cast<GLvoid *>(buffer.get())); 
    glReadBuffer(GL_BACK); 

    FlipImage(buffer.get(), width, height); 

    // Generate a BMP files for testing purposes 
    SaveRGB("screenshot.bmp", buffer.get(), width, height); 

    jpeg_compress_struct cinfo; 
    jpeg_error_mgr jerr; 
    cinfo.err = jpeg_std_error(&jerr); 
    jerr.trace_level = 10; 
    jpeg_create_compress(&cinfo); 
    boost::uint8_t *jpeg_buffer_raw = NULL; 
    unsigned long outbuffer_size = 0; 
    jpeg_mem_dest(&cinfo, &jpeg_buffer_raw, &outbuffer_size); 

    cinfo.image_width = width; 
    cinfo.image_height = height; 
    cinfo.input_components = 3; 
    cinfo.in_color_space = JCS_RGB; 
    jpeg_set_defaults(&cinfo); 

    jpeg_set_quality(&cinfo, 100, true); 
    jpeg_start_compress(&cinfo, true); 
    int row_stride = width * 3; 
    JSAMPROW row_pointer[1]; 
    int counter = 0; 
    std::cout << boost::format("height: %d\n") % height; 
    boost::uint8_t *r_buffer = buffer.get(); 
    while (cinfo.next_scanline < cinfo.image_height) { 
    row_pointer[0] = &r_buffer[cinfo.next_scanline * row_stride]; 
    jpeg_write_scanlines(&cinfo, row_pointer, 1); 
    std::cout << boost::format("current line: %d\n") % (counter++); 
    } 
    jpeg_finish_compress(&cinfo); 
    jpeg_destroy_compress(&cinfo); 
    std::ofstream jpegfile("screenshot.jpg"); 
    jpegfile.write(reinterpret_cast<const char*>(jpeg_buffer_raw), outbuffer_size); 
    jpegfile.flush(); 
    // calling free(jpeg_buffer_raw); or delete[] jpeg_buffer_raw; generates an error 
} 

이 함수는 다음 JPEG 화상 생성 메모리 목적지 버전 : 비교함으로써

enter image description here

는, 비트 맵 파일을 저장하는 라인이 하나 생성

enter image description here

답변

0

문제는 발견했습니다. FILE * 처리기가 아닙니다. dll의 테이블. 정적 버전의 라이브러리를 사용하면 문제가 해결됩니다.

std::ofstream jpegfile("screenshot.jpg", std::ios_base::out | std::ios_base::binary); 
: 메모리 버전

은 이와 같은 파일을 개방함으로써 해결 될 수있다

관련 문제