C+中的JPEG图像旋转+;使用libjpeg 我试图在LIJPEG V9中基于EXIF元数据中存在的“定位”参数在JC++中旋转JPEG图像。我能够得到“方向”参数,并在此基础上,我还能够将图像旋转到另一个文件中,使旋转后的图像对应于“方向”值1

C+中的JPEG图像旋转+;使用libjpeg 我试图在LIJPEG V9中基于EXIF元数据中存在的“定位”参数在JC++中旋转JPEG图像。我能够得到“方向”参数,并在此基础上,我还能够将图像旋转到另一个文件中,使旋转后的图像对应于“方向”值1,c++,image-rotation,libjpeg,C++,Image Rotation,Libjpeg,请参阅我从“jpegtran.c”文件中获取的代码,该代码工作正常(读取EXIF元数据代码不存在): #包括 #包括 #包括 #包括“transupp.h” void setTransformation(jpeg_transform_info*transformObj、JXFORM_代码转换){ transformObj->perfect=FALSE; transformObj->trim=FALSE; transformObj->force_grayscale=FALSE; transform

请参阅我从“jpegtran.c”文件中获取的代码,该代码工作正常(读取EXIF元数据代码不存在):

#包括
#包括
#包括
#包括“transupp.h”
void setTransformation(jpeg_transform_info*transformObj、JXFORM_代码转换){
transformObj->perfect=FALSE;
transformObj->trim=FALSE;
transformObj->force_grayscale=FALSE;
transformObj->crop=FALSE;
transformObj->transform=转换;
}
无效释放器(j_解压缩\u ptr srcPtr,j_压缩\u ptr destPtr){
jpeg_完成_压缩(destPtr);
jpeg_销毁_压缩(destPtr);
(无效)jpeg_完成_解压缩(srcPtr);
jpeg_销毁_解压缩(srcPtr);
}
void rotateImage(常量字符*输入文件名,常量字符*输出文件名,JXFORM_代码转换值){
FILE*inputFile=fopen(inputFilename,“r”);
if(inputFile==NULL){

std::Cerr是否可以指定发送数据的应用程序所接受的数据格式?如果目标应用程序接受,则可以像您看起来那样旋转未压缩像素数据的像素矩阵。我还建议将旋转后的矩阵保存到磁盘(或在屏幕上显示)因此,您可以检查旋转是否正确。@PedroBoechat,谢谢您的回答。在中,旋转涉及使用DCT系数和其他步骤,我不理解。因此,我认为从这一点来看,我的矩阵旋转代码似乎不正确。不是吗?从第一个代码开始,我从解压缩数据压缩旋转图像。这然后解压旋转后的图像,应用程序接受其数据。因此,格式为正常原始RGB 24位。请指定要发送数据的应用程序接受的数据格式。如果目标应用程序接受,则可以像您看起来那样旋转未压缩像素数据的像素矩阵。我建议还建议将旋转矩阵保存到磁盘(或在屏幕上显示)因此,您可以检查旋转是否正确。@PedroBoechat,谢谢您的回答。在中,旋转涉及使用DCT系数和其他步骤,我不理解。因此,我认为从这一点来看,我的矩阵旋转代码似乎不正确。不是吗?从第一个代码开始,我从解压缩数据压缩旋转图像。这旋转后的图像被解压,其数据被应用程序接受。因此,格式为正常原始RGB 24位。
#include <iostream>
#include <jpeglib.h>
#include <jerror.h>

#include "transupp.h"

void setTransformation(jpeg_transform_info *transformObj, JXFORM_CODE transformation){
    transformObj->perfect = FALSE;
    transformObj->trim = FALSE;
    transformObj->force_grayscale = FALSE;
    transformObj->crop = FALSE;
    transformObj->transform = transformation;
}

void releaseRes(j_decompress_ptr srcPtr, j_compress_ptr destPtr){
    
    jpeg_finish_compress(destPtr);
    jpeg_destroy_compress(destPtr);

    (void) jpeg_finish_decompress(srcPtr);
    jpeg_destroy_decompress(srcPtr);
}

void rotateImage(const char *inputFilename, const char *outputFilename, JXFORM_CODE transformVal){

    FILE *inputFile = fopen(inputFilename, "r");
    if(inputFile==NULL){
        std::cerr<<"ERROR: cannot open input file\n";
        return;
    }

    struct jpeg_decompress_struct srcObj;
    struct jpeg_error_mgr srcErrMgr;
    
    struct jpeg_compress_struct destObj;
    struct jpeg_error_mgr destErrMgr;

    jvirt_barray_ptr *srcCoefArr;
    jvirt_barray_ptr *destCoefArr;

    //transformation object
    jpeg_transform_info transformObj;

    //set error handler
    srcObj.err = jpeg_std_error(&srcErrMgr);
    jpeg_create_decompress(&srcObj);

    destObj.err = jpeg_std_error(&destErrMgr);
    jpeg_create_compress(&destObj);

    //set the transformation properties
    setTransformation(&transformObj, transformVal);

    jpeg_stdio_src(&srcObj, inputFile);
    JCOPY_OPTION copyOpt = JCOPYOPT_DEFAULT;

    jcopy_markers_setup(&srcObj, copyOpt);

    (void) jpeg_read_header(&srcObj, TRUE);

    if(!jtransform_request_workspace(&srcObj, &transformObj)){
        std::cerr<<"Transformation is not perfect\n";
        return;
    }

    srcCoefArr = jpeg_read_coefficients(&srcObj);
    jpeg_copy_critical_parameters(&srcObj, &destObj);

    destCoefArr = jtransform_adjust_parameters(&srcObj, &destObj, srcCoefArr, &transformObj);

    FILE *outputFile = fopen(outputFilename, "wb");
    if(outputFile==NULL){
        std::cerr<<"ERROR: cannot open output file\n";
        fclose(inputFile);    
        releaseRes(&srcObj, &destObj);
        return;
    }

    jpeg_stdio_dest(&destObj, outputFile);

    jpeg_write_coefficients(&destObj, destCoefArr);

    jcopy_markers_execute(&srcObj, &destObj, copyOpt);

    jtransform_execute_transformation(&srcObj, &destObj, srcCoefArr, &transformObj);

    releaseRes(&srcObj, &destObj);
    //close files
    fclose(inputFile);
    fclose(outputFile);
}
void rotateImage(const char *filename){
    FILE *file = fopen(filename, "r");
    if(!file){
        std::cerr<<"Error in reading file\n";
        return;
    }

    struct jpeg_decompress_struct info;
    struct jpeg_error_mgr jerr;
    
    info.err = jpeg_std_error(&jerr);

    jpeg_CreateDecompress(&info, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct));
        
    jpeg_stdio_src(&info, file);

    (void) jpeg_read_header(&info, TRUE);
    jpeg_start_decompress(&info);

    uint32_t channels = 3;
    uint32_t rowStride = info.output_width * channels;
    uint64_t dataSize = rowStride * info.output_height;

    unsigned char *buffer = new unsigned char[dataSize];
    unsigned char *rowData[1];

    while(info.output_scanline < info.output_height){
        //initial value of output_Scanline state var is 0
        rowData[0] = buffer + info.output_scanline * rowStride; 
        jpeg_read_scanlines(&info, rowData, 1);
    }

    /*Now, i want to rotate this buffer (or with other temp buffer without compression as in 
     first code) as per "orientation", either 90, 180, 270*/

    /* here */

    jpeg_finish_decompress(&info);
    jpeg_destroy_decompress(&info);
    fclose(file);
    delete buffer;
}
//90 degree clockwise
unsigned char *tmpBuf = new unsigned char[dataSize];
int row = info.output_height;
int col = info.output_width;
for(int i=0; i<row; i+=1){
    for(int j=0;j<col; j+=1){
        //copied 3 bytes as each pixed takes 3 bytes for RGB
        memcpy(tmpBuf + (j*row + row-i-1)*3, buffer + (i*col + j)*3, 3);
    }
}