How to keep all jpeg markers?

Anything you want added or changed in future versions of ZoneMinder? Post here and there's a chance it will get in! Search to make sure it hasn't already been requested.
Post Reply
moonug
Posts: 3
Joined: Tue Mar 06, 2012 6:53 am

How to keep all jpeg markers?

Post by moonug »

Cameras axis retain some information as markers, but zm removes all markers during processing.
I tried to implement the preservation of markers in the processing, but did not succeed.
Perhaps the solution already exists?
moonug
Posts: 3
Joined: Tue Mar 06, 2012 6:53 am

Re: How to keep all jpeg markers?

Post by moonug »

I implemented this feature. But I can not attach a diff file: "The extension diff is not allowed".
moonug
Posts: 3
Joined: Tue Mar 06, 2012 6:53 am

Re: How to keep all jpeg markers?

Post by moonug »

I can not even insert the code - "Your post looks too spamy for a new user, please remove off-site URLs. " In the code, there are no links, but there is JPEG_CОM.. (
Flasheart
Posts: 342
Joined: Thu Jul 06, 2006 2:27 pm

Re: How to keep all jpeg markers?

Post by Flasheart »

At moonug's request, posting on their behalf.

Note: This is unchecked code, use at own risk;

Code: Select all

Code:
diff -ruw ZoneMinder-1.25.0/src/zm_image.cpp zm/src/zm_image.cpp
--- ZoneMinder-1.25.0/src/zm_image.cpp   2011-06-21 13:19:10.000000000 +0400
+++ zm/src/zm_image.cpp   2012-04-13 13:40:05.000000000 +0400
@@ -45,8 +45,10 @@
     pixels = 0;
     colours = 0;
     size = 0;
+    markers_size = 0;
     allocation = 0;
     buffer = 0;
+    markers = 0;
     blend_buffer = 0;
     text[0] = '\0';
}
@@ -60,8 +62,10 @@
     pixels = 0;
     colours = 0;
     size = 0;
+    markers_size = 0;
     allocation = 0;
     buffer = 0;
+    markers = 0;
     ReadJpeg( filename );
     blend_buffer = 0;
     text[0] = '\0';
@@ -79,13 +83,15 @@
     if ( p_buffer )
     {
         allocation = 0;
+        markers = p_buffer + size;
         buffer = p_buffer;
     }
     else
     {
-        allocation = size;
+        allocation = size+JM_SIZE;
         buffer = new uint8_t[allocation];
-        memset( buffer, 0, size );
+        markers = buffer + size;
+        memset( buffer, 0, allocation );
     }
     blend_buffer = 0;
     text[0] = '\0';
@@ -99,9 +105,11 @@
     height = p_image.height;
     pixels = p_image.pixels;
     colours = p_image.colours;
-    size = allocation = p_image.size;
+    size = p_image.size;
+    allocation = size + JM_SIZE;
     buffer = new uint8_t[allocation];
-    memcpy( buffer, p_image.buffer, size );
+    markers = buffer + size;
+    memcpy( buffer, p_image.buffer, allocation );
     blend_buffer = 0;
     strncpy( text, p_image.text, sizeof(text) );
}
@@ -170,6 +178,7 @@
     {
         delete[] buffer;
         buffer = 0;
+        markers = 0;
         allocation = 0;
     }
     width = height = colours = size = 0;
@@ -184,15 +193,16 @@
         pixels = width*height;
         colours = p_colours;
         size = width*height*colours;
-        if ( allocation < size )
+        if ( allocation < size + JM_SIZE )
         {
-            allocation = size;
+            allocation = size + JM_SIZE;
             delete[] buffer;
             buffer = new uint8_t[allocation];
-            memset( buffer, 0, size );
+            markers = buffer + size;
+            memset( buffer, 0, allocation );
         }
     }
-    memcpy( buffer, new_buffer, size );
+    memcpy( buffer, new_buffer, allocation );
}

void Image::Assign( const Image &image )
@@ -204,15 +214,16 @@
         pixels = width*height;
         colours = image.colours;
         size = width*height*colours;
-        if ( allocation < size )
+        if ( allocation < size + JM_SIZE )
         {
-            allocation = size;
+            allocation = size + JM_SIZE;
             delete[] buffer;
             buffer = new uint8_t[allocation];
-            memset( buffer, 0, size );
+            markers = buffer + size;
+            memset( buffer, 0, allocation );
         }
     }
-    memcpy( buffer, image.buffer, size );
+    memcpy( buffer, image.buffer, allocation );
}

Image *Image::HighlightEdges( Rgb colour, const Box *limits )
@@ -267,13 +278,13 @@
      return( false );
   }

-   if ( statbuf.st_size != size )
+   if ( statbuf.st_size != size + JM_SIZE )
   {
      Error( "Raw file size mismatch, expected %d bytes, found %ld", size, statbuf.st_size );
      return( false );
   }

-   if ( fread( buffer, size, 1, infile ) < 1 )
+   if ( fread( buffer, size + JM_SIZE, 1, infile ) < 1 )
     {
         Fatal( "Unable to read from '%s': %s", filename, strerror(errno) );
         return( false );
@@ -286,6 +297,7 @@

bool Image::WriteRaw( const char *filename ) const
{
   FILE *outfile;
   if ( (outfile = fopen( filename, "wb" )) == NULL )
   {
@@ -293,7 +305,7 @@
      return( false );
   }

-   if ( fwrite( buffer, size, 1, outfile ) != 1 )
+   if ( fwrite( buffer, size+JM_SIZE, 1, outfile ) != 1 )
     {
         Error( "Unable to write to '%s': %s", filename, strerror(errno) );
         return( false );
@@ -304,6 +316,108 @@
   return( true );
}

+void Image::CopyMarkers(jpeg_saved_marker_ptr src)
+{
+
+    unsigned int seek = sizeof(markers_size);
+
+    for (jpeg_saved_marker_ptr mark = src; mark; mark = mark->next) {
+        uint8_t* addr = markers + seek;
+        //         Info("Addr %x, seek %d", addr, seek);
+
+        memcpy (addr, &mark->marker, sizeof (UINT8));
+        memcpy (addr + sizeof (UINT8), &mark->data_length, sizeof (unsigned
+        int));
+        memcpy (addr + sizeof (UINT8) + sizeof (unsigned int),
+                mark->data, mark->data_length);
+
+        unsigned int rec_size = sizeof (UINT8) + sizeof (unsigned int)
+        + mark->data_length;
+        seek += rec_size;
+    }
+
+    markers_size = seek - sizeof(markers_size);
+//     Info("Marker size: %d", markers_size);
+    memcpy(markers, &markers_size, sizeof(markers_size));
+
+    /*
+    jpeg_saved_marker_ptr dstmark = dst;
+    jpeg_saved_marker_ptr prev = NULL;
+    for(jpeg_saved_marker_ptr srcmark = src; srcmark != NULL; srcmark = srcmark->next)
+    {
+//        Info("dstmark: %x, srcmark: %x", srcmark, srcmark);
+        if(!dstmark)
+        {
+            dstmark = new jpeg_marker_struct;
+//            Info("dstmark: %x, srcmark: %x", dstmark, srcmark);
+            if(prev)
+            {
+//                Info("dstmark: %x, prev: %x", dstmark, prev);
+                prev->next = dstmark;
+            }
+        }
+        dstmark->marker = srcmark->marker;
+        dstmark->data_length = srcmark->data_length;
+        dstmark->original_length = srcmark->original_length;
+//        unsigned int data_size = dstmark->data_length*sizeof(JOCTET);
+        dstmark->data = (JOCTET*)malloc(dstmark->data_length);
+        memcpy(dstmark->data, srcmark->data, srcmark->data_length);
+        if(srcmark->next)
+        {
+            prev = dstmark;
+        }
+        else
+        {
+            prev = NULL;
+        }
+
+        dstmark = NULL;
+    }*/
+}
+
+
+void Image::GetMarkers (jpeg_saved_marker_ptr out) const {
+    unsigned int seek = sizeof(markers_size);
+    jpeg_saved_marker_ptr mark = out;
+    jpeg_saved_marker_ptr prev = NULL;
+    int markers_s = 0;
+
+    memcpy (&markers_s, markers, sizeof(markers_size));
+//     Info("Marker Size: %d", markers_s);
+    while (seek < markers_s + sizeof(markers_s)) {
+        if (!mark) {
+            mark = new jpeg_marker_struct;
+        }
+
+        if (prev) {
+            prev->next = mark;
+        }
+
+        const uint8_t* addr = markers + seek;
+
+        memcpy (&mark->marker, addr, sizeof (UINT8));
+
+        if (mark->marker > 0) {
+            memcpy (&mark->data_length, addr + sizeof (UINT8),
+                    sizeof (unsigned int));
+
+            mark->data = new JOCTET[mark->data_length];
+
+            memcpy (mark->data, addr + sizeof (UINT8) + sizeof (unsigned int),
+                    mark->data_length);
+            mark->original_length = mark->data_length;
+            seek += sizeof (UINT8) + sizeof (unsigned int) + mark->data_length;
+            mark->next = NULL;
+            prev = mark;
+            mark = NULL;
+        } else {
+            seek = markers_s + sizeof(markers_s);
+        }
+    }
+
+}
+
+
bool Image::ReadJpeg( const char *filename )
{
   struct jpeg_decompress_struct *cinfo = jpg_dcinfo;
@@ -332,8 +446,10 @@
   }

   jpeg_stdio_src( cinfo, infile );
+    jpeg_save_markers(cinfo, JPEG_COM, 0xffff);

   jpeg_read_header( cinfo, TRUE );
+    this->CopyMarkers(cinfo->marker_list);

   if ( cinfo->image_width != width || cinfo->image_height != height || cinfo->num_components != colours )
   {
@@ -349,11 +465,12 @@
             return( false );
         }
      size = width*height*colours;
-      if ( !buffer || allocation < size )
+      if ( !buffer || allocation < size + JM_SIZE)
      {
-         allocation = size;
+         allocation = size + JM_SIZE;
         delete[] buffer;
         buffer = new uint8_t[allocation];
+            markers = buffer + size;
      }
   }

@@ -424,6 +541,15 @@
   {
      jpeg_write_marker( cinfo, JPEG_COM, (const JOCTET *)text, strlen(text) );
   }
+    jpeg_saved_marker_ptr markers_list = new jpeg_marker_struct;
+    this->GetMarkers(markers_list);
+    for (jpeg_saved_marker_ptr marker = markers_list; marker != NULL; marker = marker->next)
+    {
+        //Info("Write marker");
+        jpeg_write_marker(cinfo, marker->marker, marker->data, marker->data_length);
+    }
+
+

   JSAMPROW row_pointer;   /* pointer to a single row */
   int row_stride = cinfo->image_width * cinfo->input_components;   /* physical row width in buffer */
@@ -461,7 +587,10 @@

   zm_jpeg_mem_src( cinfo, inbuffer, inbuffer_size );

+    jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
+
   jpeg_read_header( cinfo, TRUE );
+    this->CopyMarkers(cinfo->marker_list);

   if ( cinfo->image_width != width || cinfo->image_height != height || cinfo->num_components != colours )
   {
@@ -539,6 +668,13 @@
   cinfo->dct_method = JDCT_FASTEST;

   jpeg_start_compress( cinfo, TRUE );
+    jpeg_saved_marker_ptr markers_list = new jpeg_marker_struct;
+    this->GetMarkers(markers_list);
+    for (jpeg_saved_marker_ptr marker = markers_list; marker != NULL; marker = marker->next)
+    {
+        //Info("Write marker");
+        jpeg_write_marker(cinfo, marker->marker, marker->data, marker->data_length);
+    }

   JSAMPROW row_pointer;   /* pointer to a single row */
   int row_stride = cinfo->image_width * cinfo->input_components;   /* physical row width in buffer */
diff -ruw ZoneMinder-1.25.0/src/zm_image.h zm/src/zm_image.h
--- ZoneMinder-1.25.0/src/zm_image.h   2011-02-15 14:18:42.000000000 +0300
+++ zm/src/zm_image.h   2012-04-13 13:40:05.000000000 +0400
@@ -20,6 +20,8 @@
#ifndef ZM_IMAGE_H
#define ZM_IMAGE_H

+#define JM_SIZE 0xffff
+
#include "zm.h"
extern "C"
{
@@ -89,6 +91,8 @@
   int size;
     int allocation;
   uint8_t *buffer;
+    uint8_t *markers;
+    int markers_size;
   bool our_buffer;
   char text[1024];

@@ -106,6 +110,8 @@
   Image( const Image &p_image );
   ~Image();

+
+
   inline int Width() const { return( width ); }
   inline int Height() const { return( height ); }
   inline int Pixels() const { return( pixels ); }
@@ -115,6 +121,8 @@
   inline uint8_t *Buffer( unsigned int x, unsigned int y= 0 ) const { return( &buffer[colours*((y*width)+x)] ); }

     void Empty();
+   void CopyMarkers(jpeg_saved_marker_ptr);
+    void GetMarkers(jpeg_saved_marker_ptr) const;
   void Assign( int p_width, int p_height, int p_colours, unsigned char *new_buffer );
   void Assign( const Image &image );

@@ -124,11 +132,11 @@
         {
             Panic( "Attempt to copy different size image buffers, expected %d, got %d", size, image.size );
         }
-      memcpy( buffer, image.buffer, size );
+      memcpy( buffer, image.buffer, size + JM_SIZE);
   }
   inline Image &operator=( const unsigned char *new_buffer )
   {
-      memcpy( buffer, new_buffer, size );
+      memcpy( buffer, new_buffer, size + JM_SIZE);
      return( *this );
   }

@@ -164,7 +172,7 @@
   void Colourise();
   void DeColourise();

-   void Clear() { memset( buffer, 0, size ); }
+   void Clear() { memset( buffer, 0, size + JM_SIZE ); }
   void Fill( Rgb colour, const Box *limits=0 );
   void Fill( Rgb colour, int density, const Box *limits=0 );
   void Outline( Rgb colour, const Polygon &polygon );
diff -ruw ZoneMinder-1.25.0/src/zm_monitor.cpp zm/src/zm_monitor.cpp
--- ZoneMinder-1.25.0/src/zm_monitor.cpp   2011-03-02 15:23:10.000000000 +0300
+++ zm/src/zm_monitor.cpp   2012-04-13 13:40:05.000000000 +0400
@@ -342,7 +342,7 @@
     mem_size = sizeof(SharedData)
              + sizeof(TriggerData)
              + (image_buffer_count*sizeof(struct timeval))
-             + (image_buffer_count*camera->ImageSize());
+             + (image_buffer_count*(camera->ImageSize()+JM_SIZE));

     Debug( 1, "mem.size=%d", mem_size );
#if ZM_MEM_MAPPED
@@ -444,7 +444,7 @@
     for ( int i = 0; i < image_buffer_count; i++ )
     {
         image_buffer[i].timestamp = &(shared_timestamps[i]);
-        image_buffer[i].image = new Image( width, height, camera->Colours(), &(shared_images[i*camera->ImageSize()]) );
+        image_buffer[i].image = new Image( width, height, camera->Colours(), &(shared_images[i*(camera->ImageSize()+JM_SIZE)]) );
     }
     if ( !n_zones )
     {
Post Reply