shushus

Спринт 15. Protobuf — знакомство и установка.

May 31st, 2023
642
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.33 KB | None | 0 0
  1.  
  2. *** PACKAGE ImgConverter ***
  3.  
  4. -----------------------------------------------------------------------
  5. CMakeLists.txt
  6. -----------------------------------------------------------------------
  7. cmake_minimum_required(VERSION 3.11)
  8.  
  9. project(Negate CXX)
  10. set(CMAKE_CXX_STANDARD 17)
  11.  
  12. add_subdirectory(../ImgLib ImgLibBuildDir)
  13.  
  14. if (CMAKE_SYSTEM_NAME MATCHES "^MINGW")
  15.     set(SYSTEM_LIBS -lstdc++)
  16. else()
  17.     set(SYSTEM_LIBS)
  18. endif()
  19.  
  20. add_executable(imgconv main.cpp)
  21.  
  22. target_include_directories(imgconv PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../ImgLib")
  23. target_link_libraries(imgconv ImgLib ${SYSTEM_LIBS})
  24. -----------------------------------------------------------------------
  25. main.cpp
  26. -----------------------------------------------------------------------
  27. #include <bmp_image.h>
  28. #include <jpeg_image.h>
  29. #include <ppm_image.h>
  30.  
  31. #include <filesystem>
  32. #include <iostream>
  33. #include <string_view>
  34.  
  35. using namespace std;
  36.  
  37. enum class Format { JPEG, PPM, BMP, UNKNOWN };
  38.  
  39. Format GetFormatByExtension(const img_lib::Path& input_file) {
  40.     const string ext = input_file.extension().string();
  41.    
  42.     if (ext == ".jpg"sv || ext == ".jpeg"sv) {
  43.         return Format::JPEG;
  44.     }
  45.     if (ext == ".ppm"sv) {
  46.         return Format::PPM;
  47.     }
  48.     if (ext == ".bmp"sv) {
  49.         return Format::BMP;
  50.     }
  51.  
  52.     return Format::UNKNOWN;
  53. }
  54.  
  55. class ImageFormatInterface {
  56. public:
  57.     virtual bool SaveImage(const img_lib::Path& file, const img_lib::Image& image) const = 0;
  58.     virtual img_lib::Image LoadImage(const img_lib::Path& file) const = 0;
  59. };
  60.  
  61. namespace format_interfaces {
  62.  
  63. class PPM : public ImageFormatInterface {
  64. public:
  65.     bool SaveImage(const img_lib::Path& file, const img_lib::Image& image) const override {
  66.         return img_lib::SavePPM(file, image);
  67.     }
  68.  
  69.     img_lib::Image LoadImage(const img_lib::Path& file) const override {
  70.         return img_lib::LoadPPM(file);
  71.     }
  72. };
  73.  
  74. class JPEG : public ImageFormatInterface {
  75. public:
  76.     bool SaveImage(const img_lib::Path& file, const img_lib::Image& image) const override {
  77.         return img_lib::SaveJPEG(file, image);
  78.     }
  79.  
  80.     img_lib::Image LoadImage(const img_lib::Path& file) const override {
  81.         return img_lib::LoadJPEG(file);
  82.     }
  83. };
  84.  
  85. class BMP : public ImageFormatInterface {
  86. public:
  87.     bool SaveImage(const img_lib::Path& file, const img_lib::Image& image) const override {
  88.         return img_lib::SaveBMP(file, image);
  89.     }
  90.  
  91.     img_lib::Image LoadImage(const img_lib::Path& file) const override {
  92.         return img_lib::LoadBMP(file);
  93.     }
  94. };
  95.  
  96. }//end namespace format_interfaces
  97.  
  98. const ImageFormatInterface* GetFormatInterface(const img_lib::Path& path) {
  99.    
  100.     Format format = GetFormatByExtension(path);
  101.    
  102.     if (format == Format::UNKNOWN) {
  103.         return nullptr;
  104.     }
  105.  
  106.     static const format_interfaces::PPM ppmInterface;
  107.     static const format_interfaces::JPEG jpegInterface;
  108.     static const format_interfaces::BMP bmpInterface;
  109.  
  110.     switch (format) {
  111.         case Format::UNKNOWN:
  112.             return nullptr;
  113.  
  114.         case Format::PPM:
  115.             return &ppmInterface;
  116.  
  117.         case Format::JPEG:
  118.             return &jpegInterface;
  119.  
  120.         case Format::BMP:
  121.             return &bmpInterface;
  122.     }
  123.  
  124.     return nullptr;
  125. }
  126.  
  127. int main(int argc, const char** argv) {
  128.    
  129.     if (argc != 3) {
  130.         cerr << "Usage: "sv << argv[0] << " <in_file> <out_file>"sv << endl;
  131.         return 1;
  132.     }
  133.  
  134.     img_lib::Path in_path = argv[1];
  135.     img_lib::Path out_path = argv[2];
  136.  
  137.     const ImageFormatInterface* in_format_interface = GetFormatInterface(in_path);
  138.     if (!in_format_interface) {
  139.         cerr << "Unknown format of the input file"sv << endl;
  140.         return 2;
  141.     }
  142.  
  143.     const ImageFormatInterface* out_format_interface = GetFormatInterface(out_path);
  144.     if (!out_format_interface) {
  145.         cerr << "Unknown format of the output file"sv << endl;
  146.         return 3;
  147.     }
  148.  
  149.     img_lib::Image image = in_format_interface->LoadImage(in_path);
  150.     if (!image) {
  151.         cerr << "Loading failed"sv << endl;
  152.         return 4;
  153.     }
  154.  
  155.     if (!out_format_interface->SaveImage(out_path, image)) {
  156.         cerr << "Saving failed"sv << endl;
  157.         return 5;
  158.     }
  159.  
  160.     cout << "Successfully converted"sv << endl;
  161. }
  162.  
  163. *** PACKAGE ImgConverter END ***
  164.  
  165. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  166.  
  167. *** PACKAGE ImgLib ***
  168.  
  169. -----------------------------------------------------------------------
  170. CMakeLists.txt
  171. -----------------------------------------------------------------------
  172. cmake_minimum_required(VERSION 3.11)
  173.  
  174. project(ImgLib CXX)
  175. set(CMAKE_CXX_STANDARD 17)
  176.  
  177. set(LIBJPEG_DIR CACHE STRING "LibJPEG static library directory")
  178.  
  179. if(NOT LIBJPEG_DIR)
  180.     message(FATAL_ERROR "Please, specify LibJPEG directory via -DLIBJPEG_DIR=<dir>")
  181. endif()
  182.     message(STATUS "LibJPEG dir is ${LIBJPEG_DIR}, change via -DLIBJPEG_DIR=<dir>")
  183.  
  184. set(IMGLIB_MAIN_FILES img_lib.h img_lib.cpp)
  185.  
  186. set(IMGLIB_FORMAT_FILES ppm_image.h ppm_image.cpp
  187.                         jpeg_image.h jpeg_image.cpp
  188.                         bmp_image.h bmp_image.cpp)
  189.  
  190. add_library(ImgLib STATIC ${IMGLIB_MAIN_FILES}
  191.                           ${IMGLIB_FORMAT_FILES})
  192.  
  193. target_include_directories(ImgLib PUBLIC "${LIBJPEG_DIR}/include")
  194. target_link_directories(ImgLib INTERFACE "${LIBJPEG_DIR}/lib/$<IF:$<CONFIG:Debug>,Debug,Release>")
  195. target_link_libraries(ImgLib INTERFACE jpeg)
  196. -----------------------------------------------------------------------
  197. jpeg_image.h
  198. -----------------------------------------------------------------------
  199. #pragma once
  200. #include "img_lib.h"
  201.  
  202. #include <filesystem>
  203.  
  204. namespace img_lib {
  205.    
  206. using Path = std::filesystem::path;
  207.  
  208. bool SaveJPEG(const Path& file, const Image& image);
  209. Image LoadJPEG(const Path& file);
  210.  
  211. }//end namespace img_lib
  212. -----------------------------------------------------------------------
  213. jpeg_image.cpp
  214. -----------------------------------------------------------------------
  215. #include "ppm_image.h"
  216.  
  217. #include <array>
  218. #include <fstream>
  219. #include <stdio.h>
  220. #include <setjmp.h>
  221. #include <vector>
  222.  
  223. #include <jpeglib.h>
  224.  
  225. using namespace std;
  226.  
  227. namespace img_lib {
  228.  
  229. struct my_error_mgr {
  230.     struct jpeg_error_mgr pub;
  231.     jmp_buf setjmp_buffer;
  232. };
  233.  
  234. typedef struct my_error_mgr* my_error_ptr;
  235.  
  236. METHODDEF(void)
  237. my_error_exit (j_common_ptr cinfo) {
  238.     my_error_ptr myerr = (my_error_ptr) cinfo->err;
  239.     (*cinfo->err->output_message) (cinfo);
  240.     longjmp(myerr->setjmp_buffer, 1);
  241. }
  242.  
  243. bool SaveJPEG(const Path& file, const Image& image) {
  244.  
  245.     jpeg_compress_struct cinfo;
  246.     jpeg_error_mgr jerr;
  247.  
  248.     FILE* outfile;              
  249.     JSAMPROW row_pointer[1];    
  250.     int row_stride;                
  251.  
  252.     cinfo.err = jpeg_std_error(&jerr);
  253.     jpeg_create_compress(&cinfo);
  254.  
  255. #ifdef _MSC_VER
  256.     if ((outfile = _wfopen(file.wstring().c_str(), "wb")) == NULL) {
  257. #else
  258.     if ((outfile = fopen(file.string().c_str(), "wb")) == NULL) {
  259. #endif
  260.     return false;}
  261.    
  262.     jpeg_stdio_dest(&cinfo, outfile);
  263.  
  264.     cinfo.image_width = image.GetWidth();
  265.     cinfo.image_height = image.GetHeight();
  266.     cinfo.input_components = 3;      
  267.     cinfo.in_color_space = JCS_RGB;  
  268.  
  269.     jpeg_set_defaults(&cinfo);
  270.     jpeg_start_compress(&cinfo, TRUE);
  271.     row_stride = image.GetWidth() * 3;
  272.  
  273.     while (cinfo.next_scanline < cinfo.image_height) {      
  274.         std::vector<JSAMPLE> jsample(row_stride);
  275.        
  276.         for (int i = 0; i < image.GetWidth(); ++i) {
  277.            
  278.             jsample[3 * i] = JSAMPLE(image.GetLine(cinfo.next_scanline)[i].r);
  279.             jsample[1 + 3 * i] = JSAMPLE(image.GetLine(cinfo.next_scanline)[i].g);
  280.             jsample[2 + 3 * i] = JSAMPLE(image.GetLine(cinfo.next_scanline)[i].b);
  281.         }
  282.        
  283.         row_pointer[0] = &jsample[0];
  284.         (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
  285.     }
  286.  
  287.     jpeg_finish_compress(&cinfo);
  288.     fclose(outfile);
  289.  
  290.     jpeg_destroy_compress(&cinfo);
  291.    
  292.     return true;
  293. }
  294.  
  295. void SaveScanlineToImage(const JSAMPLE* row, int y, Image& out_image) {
  296.    
  297.     Color* line = out_image.GetLine(y);
  298.    
  299.     for (int x = 0; x < out_image.GetWidth(); ++x) {
  300.        
  301.         const JSAMPLE* pixel = row + x * 3;
  302.         line[x] = Color{byte{pixel[0]}, byte{pixel[1]}, byte{pixel[2]}, byte{255}};
  303.     }
  304. }
  305.  
  306. Image LoadJPEG(const Path& file) {
  307.     jpeg_decompress_struct cinfo;
  308.     my_error_mgr jerr;
  309.    
  310.     FILE* infile;
  311.     JSAMPARRAY buffer;
  312.     int row_stride;
  313.  
  314. #ifdef _MSC_VER
  315.     if ((infile = _wfopen(file.wstring().c_str(), "rb")) == NULL) {
  316. #else
  317.     if ((infile = fopen(file.string().c_str(), "rb")) == NULL) {
  318. #endif
  319.         return {};
  320.     }
  321.  
  322.     cinfo.err = jpeg_std_error(&jerr.pub);
  323.     jerr.pub.error_exit = my_error_exit;
  324.  
  325.     if (setjmp(jerr.setjmp_buffer)) {
  326.         jpeg_destroy_decompress(&cinfo);
  327.         fclose(infile);
  328.         return {};
  329.     }
  330.  
  331.     jpeg_create_decompress(&cinfo);
  332.     jpeg_stdio_src(&cinfo, infile);
  333.     (void) jpeg_read_header(&cinfo, TRUE);
  334.     cinfo.out_color_space = JCS_RGB;
  335.     cinfo.output_components = 3;
  336.     (void) jpeg_start_decompress(&cinfo);
  337.    
  338.     row_stride = cinfo.output_width * cinfo.output_components;    
  339.     buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
  340.  
  341.     Image result(cinfo.output_width, cinfo.output_height, Color::Black());
  342.  
  343.     while (cinfo.output_scanline < cinfo.output_height) {
  344.         int y = cinfo.output_scanline;
  345.         (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  346.  
  347.         SaveScanlineToImage(buffer[0], y, result);
  348.     }
  349.  
  350.     (void) jpeg_finish_decompress(&cinfo);
  351.  
  352.     jpeg_destroy_decompress(&cinfo);
  353.     fclose(infile);
  354.  
  355.     return result;
  356. }
  357.  
  358. }//end namespace img_lib
  359. -----------------------------------------------------------------------
  360. img_lib.h
  361. -----------------------------------------------------------------------
  362. #pragma once
  363.  
  364. #include <array>
  365. #include <cassert>
  366. #include <cstddef>
  367. #include <vector>
  368.  
  369. namespace img_lib {
  370.  
  371. struct Size {
  372.     int width;
  373.     int height;
  374. };
  375.  
  376. struct Color {
  377.    
  378.     static Color Black() {
  379.        
  380.         return {std::byte{0},
  381.                 std::byte{0},
  382.                 std::byte{0},
  383.                 std::byte{255}};
  384.     }
  385.  
  386.     std::byte r, g, b, a;
  387. };
  388.  
  389. class Image {
  390. public:
  391.  
  392.     Image() = default;
  393.  
  394.     Image(int w, int h, Color fill);
  395.  
  396.     Color GetPixel(int x, int y) const {return const_cast<Image*>(this)->GetPixel(x, y);}
  397.    
  398.     Color& GetPixel(int x, int y) {
  399.         assert(x < GetWidth() && y < GetHeight() && x >= 0 && y >= 0);
  400.         return GetLine(y)[x];
  401.     }
  402.  
  403.     Color* GetLine(int y);
  404.     const Color* GetLine(int y) const;
  405.  
  406.     int GetWidth() const;
  407.     int GetHeight() const;
  408.  
  409.     int GetStep() const;
  410.  
  411.     explicit operator bool() const {return GetWidth() > 0 && GetHeight() > 0;}
  412.     bool operator!() const {return !operator bool();}
  413.  
  414. private:
  415.     int width_ = 0;
  416.     int height_ = 0;
  417.     int step_;
  418.  
  419.     std::vector<Color> pixels_;
  420. };
  421.  
  422. }//end namespace img_lib
  423. -----------------------------------------------------------------------
  424. img_lib.cpp
  425. -----------------------------------------------------------------------
  426. #include "img_lib.h"
  427.  
  428. namespace img_lib {
  429.  
  430. Image::Image(int w, int h, Color fill) : width_(w)
  431.                                        , height_(h)
  432.                                        , step_(w)
  433.                                        , pixels_(step_ * height_, fill) {}
  434.  
  435. Color* Image::GetLine(int y) {
  436.     assert(y >= 0 && y < height_);
  437.     return pixels_.data() + step_ * y;
  438. }
  439.  
  440. const Color* Image::GetLine(int y) const {return const_cast<Image*>(this)->GetLine(y);}
  441. int Image::GetWidth() const {return width_;}
  442. int Image::GetHeight() const {return height_;}
  443. int Image::GetStep() const {return step_;}
  444.  
  445. }//end namespace img_lib
  446. -----------------------------------------------------------------------
  447. ppm_image.h
  448. -----------------------------------------------------------------------
  449. #pragma once
  450. #include "img_lib.h"
  451.  
  452. #include <filesystem>
  453.  
  454. namespace img_lib {
  455.    
  456. using Path = std::filesystem::path;
  457.  
  458. bool SavePPM(const Path& file, const Image& image);
  459. Image LoadPPM(const Path& file);
  460.  
  461. }//end namespace img_lib
  462. -----------------------------------------------------------------------
  463. ppm_image.cpp
  464. -----------------------------------------------------------------------
  465. #include "ppm_image.h"
  466.  
  467. #include <array>
  468. #include <fstream>
  469. #include <string_view>
  470.  
  471. using namespace std;
  472.  
  473. namespace img_lib {
  474.  
  475. static const string_view PPM_SIG = "P6"sv;
  476. static const int PPM_MAX = 255;
  477.  
  478. bool SavePPM(const Path& file, const Image& image) {
  479.    
  480.     ofstream out(file, ios::binary);
  481.  
  482.     out << PPM_SIG << '\n' << image.GetWidth() << ' ' << image.GetHeight() << '\n' << PPM_MAX << '\n';
  483.  
  484.     const int width = image.GetWidth();
  485.     const int height = image.GetHeight();
  486.    
  487.     std::vector<char> buff(width * 3);
  488.  
  489.     for (int i = 0; i < height; ++i) {
  490.        
  491.         const Color* line = image.GetLine(i);
  492.        
  493.         for (int j = 0; j < width; ++j) {
  494.             buff[3 * j] = static_cast<char>(line[j].r);
  495.             buff[1 + 3 * j] = static_cast<char>(line[j].g);
  496.             buff[2 + 3 * j] = static_cast<char>(line[j].b);
  497.         }
  498.        
  499.         out.write(buff.data(), width * 3);
  500.     }
  501.  
  502.     return out.good();
  503. }
  504.  
  505. Image LoadPPM(const Path& file) {
  506.    
  507.     ifstream ifs(file, ios::binary);
  508.    
  509.     std::string sign;
  510.    
  511.     int width;
  512.     int height;
  513.     int color_max;
  514.     auto color = Color::Black();
  515.    
  516.     ifs >> sign >> width >> height >> color_max;
  517.  
  518.     if (sign != PPM_SIG || color_max != PPM_MAX) {return {};}
  519.  
  520.     const char next = ifs.get();
  521.     if (next != '\n') {return {};}
  522.  
  523.     Image result(width, height, color);
  524.     std::vector<char> buff(width * 3);
  525.  
  526.     for (int i = 0; i < height; ++i) {
  527.        
  528.         Color* line = result.GetLine(i);
  529.         ifs.read(buff.data(), width * 3);
  530.  
  531.         for (int j = 0; j < width; ++j) {
  532.             line[j].r = static_cast<byte>(buff[3 * j]);
  533.             line[j].g = static_cast<byte>(buff[1 + 3 * j]);
  534.             line[j].b = static_cast<byte>(buff[2 + 3 * j]);
  535.         }
  536.     }
  537.  
  538.     return result;
  539. }
  540.  
  541. }//end namespace img_lib
  542. -----------------------------------------------------------------------
  543. bmp_image.h
  544. -----------------------------------------------------------------------
  545. #pragma once
  546. #include "img_lib.h"
  547.  
  548. #include <filesystem>
  549.  
  550. namespace img_lib {
  551.    
  552. using Path = std::filesystem::path;
  553.  
  554. bool SaveBMP(const Path& file, const Image& image);
  555. Image LoadBMP(const Path& file);
  556.  
  557. }//end namespace img_lib
  558. -----------------------------------------------------------------------
  559. bmp_image.cpp
  560. -----------------------------------------------------------------------
  561. #include "bmp_image.h"
  562. #include "pack_defines.h"
  563.  
  564. #include <array>
  565. #include <fstream>
  566. #include <string_view>
  567.  
  568. using namespace std;
  569.  
  570. namespace img_lib {
  571.  
  572. PACKED_STRUCT_BEGIN BitmapFileHeader {
  573.     char sign1 = 'B';
  574.     char sign2 = 'M';
  575.    
  576.     uint32_t header_size = 0;
  577.    
  578.     uint32_t reserved_space = 0;
  579.     uint32_t indention = 54;
  580.    
  581. } PACKED_STRUCT_END
  582.  
  583. PACKED_STRUCT_BEGIN BitmapInfoHeader {
  584.     uint32_t header_size = 40;
  585.    
  586.     uint32_t width = 0;
  587.     uint32_t height = 0;
  588.    
  589.     uint16_t layers = 1;
  590.     uint16_t bit_per_pixel = 24;
  591.    
  592.     uint32_t compression_type = 0;
  593.     uint32_t bytes_at_data = 0;
  594.    
  595.     int32_t vertical_pixel_per_meter = 11811;
  596.     int32_t horizontal_pixel_per_meter = 11811;
  597.    
  598.     int32_t colors_in_use = 0;
  599.     int32_t colors = 0x1000000;
  600.    
  601. } PACKED_STRUCT_END
  602.  
  603. static int GetBMPStride(int w) {return 4 * ((w * 3 + 3) / 4);}
  604.  
  605. bool SaveBMP(const Path& file, const Image& image) {
  606.    
  607.     ofstream out(file, ios::binary);
  608.    
  609.     int width = image.GetWidth();
  610.     int height = image.GetHeight();
  611.  
  612.     const int bmp_stride = GetBMPStride(width);
  613.    
  614.     BitmapFileHeader file_header;
  615.     BitmapInfoHeader info_header;
  616.    
  617.     file_header.header_size = bmp_stride * height + file_header.indention;
  618.    
  619.     info_header.width = width;
  620.     info_header.height = height;
  621.     info_header.bytes_at_data = height * bmp_stride;
  622.  
  623.     out.write(reinterpret_cast<const char*>(&file_header), 14);
  624.     out.write(reinterpret_cast<const char*>(&file_header), 40);
  625.  
  626.     std::vector<char> buff(bmp_stride);
  627.    
  628.     for (int i = height - 1; i >= 0; --i) {
  629.         const Color* line = image.GetLine(i);
  630.        
  631.         for (int j = 0; j != width; ++j) {
  632.            
  633.             buff[3 * j] = static_cast<char>(line[j].b);
  634.             buff[1 + 3 * j] = static_cast<char>(line[j].g);
  635.             buff[2 + 3 * j] = static_cast<char>(line[j].r);
  636.         }
  637.        
  638.         out.write(buff.data(), bmp_stride);
  639.     }
  640.  
  641.     return out.good();
  642. }
  643.  
  644. Image LoadBMP(const Path& file) {
  645.    
  646.     ifstream input(file, ios::binary);
  647.  
  648.     BitmapFileHeader file_header;
  649.     BitmapInfoHeader info_header;
  650.  
  651.     input.read(reinterpret_cast<char*>(&file_header), sizeof(BitmapFileHeader));
  652.     input.read(reinterpret_cast<char*>(&info_header), sizeof(BitmapInfoHeader));
  653.  
  654.     int width = info_header.width;
  655.     int height = info_header.height;
  656.     auto color = Color::Black();
  657.  
  658.     const int bmp_stride = GetBMPStride(width);
  659.    
  660.     std::vector<char> buff(bmp_stride);
  661.     Image result(width, width, color);
  662.  
  663.     for (int i = height - 1; i >= 0; --i) {
  664.        
  665.         input.read(buff.data(), bmp_stride);
  666.         Color* line = result.GetLine(i);
  667.        
  668.         for (int j = 0; j != width; ++j) {
  669.             line[j].b = static_cast<byte>(buff[j * 3]);
  670.             line[j].g = static_cast<byte>(buff[1 + j * 3]);
  671.             line[j].r = static_cast<byte>(buff[2 + j * 3]);
  672.         }
  673.     }
  674.  
  675.     return result;
  676. }
  677.  
  678. }//end namespace img_lib
  679. -----------------------------------------------------------------------
  680. pack_defines.h
  681. -----------------------------------------------------------------------
  682. #pragma once
  683.  
  684. #if !defined(ALIGNED_TYPE_BEGIN)
  685.     #if defined(_MSC_VER) || defined(__INTEL_COMPILER_BUILD_DATE)
  686.         #define PACKED_STRUCT_BEGIN \
  687.             __pragma(pack(push,1)) \
  688.             struct __declspec(align(1))
  689.         #define PACKED_STRUCT_END \
  690.             ;__pragma(pack(pop))
  691.     #else
  692.         #define PACKED_STRUCT_BEGIN \
  693.             struct
  694.         #define PACKED_STRUCT_END  __attribute__((packed));
  695.     #endif
  696. #endif
  697.  
  698. *** PACKAGE ImgLib END ***
Advertisement
Add Comment
Please, Sign In to add comment