改变DCT系数 [英] Changing DCT coefficients

查看:595
本文介绍了改变DCT系数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定使用libjpeg作为使用jpeg文件的主库。
我读过libjpg.txt文件。我很高兴图书馆能够以方便的方式读取/写入DCT系数。由于编写自己的解码器需要很长时间。

I decided to use libjpeg as the main library working with jpeg files. I've read libjpg.txt file. And I was pleased that library allows DCT coefficients reading/writing in a convenient way. Since writing an own decoder will take a long time.

我的工作与无损嵌入有关。目前我需要从文件中读取DCT系数,然后修改其中的一些并在同一文件中写入更改的系数。

My work is related to the lossless embedding. Currently I need to read DCT coefficients from a file then modify some of them and write changed coefficients in the same file.

好吧,我找到了 jpeg_write_coefficients()函数。我天真地认为我可以将它应用于解压缩对象( struct jpeg_decompress_struct )。但它不起作用,需要压缩对象。

Well, I found jpeg_write_coefficients() function. And I naively thought that I could apply it to a decompression object (struct jpeg_decompress_struct). But it does not work and requires a compression object.

我无法相信这样强大的库无法做到这一点。
我认为我很可能错过了一些东西。虽然我试着去关注。
也许写作系数可以做得更复杂。
但我不知道怎么做。

I can't believe that such the powerful library is not able to do this. I think that most likely I'm missing something. Although I tried to be attentive. Perhaps the writing coefficients can be done more sophisticated way. But I don't know how to.

如果你提出自己的想法,我会很高兴。

I will be very glad if you propose your ideas.

推荐答案

您可以使用jpeg_write_coefficients来编写已更改的DCT。

You can ue jpeg_write_coefficients to write your changed DCT.

以下信息可在 libjpeg.txt

To write the contents of a JPEG file as DCT coefficients, you must provide
the DCT coefficients stored in virtual block arrays.  You can either pass
block arrays read from an input JPEG file by jpeg_read_coefficients(), or
allocate virtual arrays from the JPEG compression object and fill them
yourself.  In either case, jpeg_write_coefficients() is substituted for
jpeg_start_compress() and jpeg_write_scanlines().  Thus the sequence is
  * Create compression object
  * Set all compression parameters as necessary
  * Request virtual arrays if needed
  * jpeg_write_coefficients()
  * jpeg_finish_compress()
  * Destroy or re-use compression object
jpeg_write_coefficients() is passed a pointer to an array of virtual block
array descriptors; the number of arrays is equal to cinfo.num_components.

The virtual arrays need only have been requested, not realized, before
jpeg_write_coefficients() is called.  A side-effect of
jpeg_write_coefficients() is to realize any virtual arrays that have been
requested from the compression object's memory manager.  Thus, when obtaining
the virtual arrays from the compression object, you should fill the arrays
after calling jpeg_write_coefficients().  The data is actually written out
when you call jpeg_finish_compress(); jpeg_write_coefficients() only writes
the file header.

When writing raw DCT coefficients, it is crucial that the JPEG quantization
tables and sampling factors match the way the data was encoded, or the
resulting file will be invalid.  For transcoding from an existing JPEG file,
we recommend using jpeg_copy_critical_parameters().  This routine initializes
all the compression parameters to default values (like jpeg_set_defaults()),
then copies the critical information from a source decompression object.
The decompression object should have just been used to read the entire
JPEG input file --- that is, it should be awaiting jpeg_finish_decompress().

jpeg_write_coefficients() marks all tables stored in the compression object
as needing to be written to the output file (thus, it acts like
jpeg_start_compress(cinfo, TRUE)).  This is for safety's sake, to avoid
emitting abbreviated JPEG files by accident.  If you really want to emit an
abbreviated JPEG file, call jpeg_suppress_tables(), or set the tables'
individual sent_table flags, between calling jpeg_write_coefficients() and
jpeg_finish_compress().

因此,要更改单个dct,您可以使用以下简单代码:
访问任何dct coeff,你需要改变四个索引,cx,bx,by,bi。
在我的代码中,我使用 blockptr_one [bi] ++; 增加一个dct Coeff

So to change a single dct, you can use the following simple code: To access any dct coeff, you need to change four index, cx, bx, by, bi. In my code, I used blockptr_one[bi]++; to increase one dct Coeff

#include <stdio.h>
#include <jpeglib.h>
#include <stdlib.h>
#include <iostream>
#include <string>    

int write_jpeg_file(std::string outname,jpeg_decompress_struct in_cinfo, jvirt_barray_ptr *coeffs_array ){

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE * infile;

    if ((infile = fopen(outname.c_str(), "wb")) == NULL) {
      fprintf(stderr, "can't open %s\n", outname.c_str());
      return 0;
    }

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, infile);

    j_compress_ptr cinfo_ptr = &cinfo;
    jpeg_copy_critical_parameters((j_decompress_ptr)&in_cinfo,cinfo_ptr);
    jpeg_write_coefficients(cinfo_ptr, coeffs_array);

    jpeg_finish_compress( &cinfo );
    jpeg_destroy_compress( &cinfo );
    fclose( infile );

    return 1;
}

int read_jpeg_file( std::string filename, std::string outname )
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE * infile;

    if ((infile = fopen(filename.c_str(), "rb")) == NULL) {
      fprintf(stderr, "can't open %s\n", filename.c_str());
      return 0;
    }

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    jpeg_stdio_src(&cinfo, infile);
    (void) jpeg_read_header(&cinfo, TRUE);


    jvirt_barray_ptr *coeffs_array = jpeg_read_coefficients(&cinfo);

    //change one dct:
    int ci = 0; // between 0 and number of image component
    int by = 0; // between 0 and compptr_one->height_in_blocks
    int bx = 0; // between 0 and compptr_one->width_in_blocks
    int bi = 0; // between 0 and 64 (8x8)
    JBLOCKARRAY buffer_one;
    JCOEFPTR blockptr_one;
    jpeg_component_info* compptr_one;
    compptr_one = cinfo.comp_info + ci;
    buffer_one = (cinfo.mem->access_virt_barray)((j_common_ptr)&cinfo, coeffs_array[ci], by, (JDIMENSION)1, FALSE);
    blockptr_one = buffer_one[0][bx];
    blockptr_one[bi]++;

    write_jpeg_file(outname, cinfo, coeffs_array);

    jpeg_finish_decompress( &cinfo );
    jpeg_destroy_decompress( &cinfo );
    fclose( infile );

    return 1;


}

int main()
{
    std::string infilename = "you_image.jpg", outfilename = "out_image.jpg";

    /* Try opening a jpeg*/
    if( read_jpeg_file( infilename, outfilename ) > 0 )
    {
        std::cout << "It's Okay..." << std::endl;
    }
    else return -1;
    return 0;
}

这篇关于改变DCT系数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆