diff -U 3 -H -d -r -N -- ZoneMinder-1.23.3/src/zm_event.cpp ZoneMinder-1.23.3_patch/src/zm_event.cpp
--- ZoneMinder-1.23.3/src/zm_event.cpp	2008-04-21 15:52:05.000000000 +0200
+++ ZoneMinder-1.23.3_patch/src/zm_event.cpp	2008-05-08 21:01:29.000000000 +0200
@@ -842,6 +842,12 @@
             Debug( 1, ( "Got SCALE command, to %d", scale ));
             break;
         }
+        case CMD_ROTATE :
+        {
+            rotate = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2];
+            Debug( 1, ( "Got ROTATE command, to %d", rotate ));
+            break;
+        }
         case CMD_PREV :
         {
             Debug( 1, ( "Got PREV command" ));
diff -U 3 -H -d -r -N -- ZoneMinder-1.23.3/src/zm_monitor.cpp ZoneMinder-1.23.3_patch/src/zm_monitor.cpp
--- ZoneMinder-1.23.3/src/zm_monitor.cpp	2008-03-13 14:36:12.000000000 +0100
+++ ZoneMinder-1.23.3_patch/src/zm_monitor.cpp	2008-05-08 21:38:34.000000000 +0200
@@ -457,7 +457,7 @@
 	return( shared_data->state );
 }
 
-int Monitor::GetImage( int index, int scale ) const
+int Monitor::GetImage( int index, int scale, int rotate ) const
 {
 	if ( index < 0 || index > image_buffer_count )
 	{
@@ -473,6 +473,10 @@
 		{
 			snap_image.Scale( scale );
 		}
+		if ( rotate != 0 )
+		{
+			snap_image.Rotate( rotate );
+		}
 
 		static char filename[PATH_MAX];
 		snprintf( filename, sizeof(filename), "%s.jpg", name );
@@ -2745,6 +2749,12 @@
             Debug( 1, ( "Got SCALE command, to %d", scale ));
             break;
         }
+        case CMD_ROTATE :
+        {
+            scale = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2];
+            Debug( 1, ( "Got ROTATE command, to %d", rotate ));
+            break;
+        }
         case CMD_QUERY :
         {
             Debug( 1, ( "Got QUERY command, sending STATUS" ));
@@ -2918,7 +2928,7 @@
     if ( type == STREAM_SINGLE )
     {
         // Not yet migrated over to stream class
-        monitor->SingleImage( scale );
+        monitor->SingleImage( scale, rotate );
         return;
     }
 
@@ -3202,11 +3212,12 @@
     closeComms();
 }
 
-void Monitor::SingleImage( int scale)
+void Monitor::SingleImage( int scale, int rotate)
 {
 	int img_buffer_size = 0;
 	static JOCTET img_buffer[ZM_MAX_IMAGE_SIZE];
 	Image scaled_image;
+	Image rotated_image;
 	int index = shared_data->last_write_index%image_buffer_count;
 	Snapshot *snap = &image_buffer[index];
 	Image *snap_image = snap->image;
@@ -3217,6 +3228,12 @@
 		scaled_image.Scale( scale );
 		snap_image = &scaled_image;
 	}
+	if ( rotate != 0 )
+	{
+		rotated_image.Assign( *snap_image );
+		rotated_image.Rotate( rotate );
+		snap_image = &rotated_image;
+	}
 	if ( !config.timestamp_on_capture )
 	{
 		TimestampImage( snap_image, snap->timestamp );
@@ -3228,9 +3245,10 @@
 	fwrite( img_buffer, img_buffer_size, 1, stdout );
 }
 
-void Monitor::SingleImageRaw( int scale)
+void Monitor::SingleImageRaw( int scale, int rotate)
 {
 	Image scaled_image;
+	Image rotated_image;
 	int index = shared_data->last_write_index%image_buffer_count;
 	Snapshot *snap = &image_buffer[index];
 	Image *snap_image = snap->image;
@@ -3241,6 +3259,12 @@
 		scaled_image.Scale( scale );
 		snap_image = &scaled_image;
 	}
+	if ( rotate != 0 )
+	{
+		rotated_image.Assign( *snap_image );
+		rotated_image.Rotate( rotate );
+		snap_image = &rotated_image;
+	}
 	if ( !config.timestamp_on_capture )
 	{
 		TimestampImage( snap_image, snap->timestamp );
@@ -3251,11 +3275,12 @@
 	fwrite( snap_image->Buffer(), snap_image->Size(), 1, stdout );
 }
 
-void Monitor::SingleImageZip( int scale)
+void Monitor::SingleImageZip( int scale, int rotate)
 {
 	unsigned long img_buffer_size = 0;
 	static Bytef img_buffer[ZM_MAX_IMAGE_SIZE];
 	Image scaled_image;
+	Image rotated_image;
 	int index = shared_data->last_write_index%image_buffer_count;
 	Snapshot *snap = &image_buffer[index];
 	Image *snap_image = snap->image;
@@ -3266,6 +3291,12 @@
 		scaled_image.Scale( scale );
 		snap_image = &scaled_image;
 	}
+	if ( rotate != 0 )
+	{
+		rotated_image.Assign( *snap_image );
+		rotated_image.Rotate( rotate );
+		snap_image = &rotated_image;
+	}
 	if ( !config.timestamp_on_capture )
 	{
 		TimestampImage( snap_image, snap->timestamp );
diff -U 3 -H -d -r -N -- ZoneMinder-1.23.3/src/zm_monitor.h ZoneMinder-1.23.3_patch/src/zm_monitor.h
--- ZoneMinder-1.23.3/src/zm_monitor.h	2008-03-13 14:36:12.000000000 +0100
+++ ZoneMinder-1.23.3_patch/src/zm_monitor.h	2008-05-08 22:12:16.000000000 +0200
@@ -280,7 +280,7 @@
     unsigned int Colours() const { return( camera->Colours() ); }
  
 	State GetState() const;
-	int GetImage( int index=-1, int scale=100 ) const;
+	int GetImage( int index=-1, int scale=100, int rotate=0 ) const;
 	struct timeval GetTimestamp( int index=-1 ) const;
 	int GetCaptureDelay() const { return( capture_delay ); }
 	int GetAlarmCaptureDelay() const { return( alarm_capture_delay ); }
@@ -336,9 +336,9 @@
 	//void StreamImages( int scale=100, int maxfps=10, time_t ttl=0, int msq_id=0 );
 	//void StreamImagesRaw( int scale=100, int maxfps=10, time_t ttl=0 );
 	//void StreamImagesZip( int scale=100, int maxfps=10, time_t ttl=0 );
-	void SingleImage( int scale=100 );
-	void SingleImageRaw( int scale=100 );
-	void SingleImageZip( int scale=100 );
+	void SingleImage( int scale=100, int rotate=0 );
+	void SingleImageRaw( int scale=100, int rotate=0 );
+	void SingleImageZip( int scale=100, int rotate=0 );
 #if HAVE_LIBAVCODEC
 	//void StreamMpeg( const char *format, int scale=100, int maxfps=10, int bitrate=100000 );
 #endif // HAVE_LIBAVCODEC
diff -U 3 -H -d -r -N -- ZoneMinder-1.23.3/src/zm_stream.cpp ZoneMinder-1.23.3_patch/src/zm_stream.cpp
--- ZoneMinder-1.23.3/src/zm_stream.cpp	2008-03-13 14:36:12.000000000 +0100
+++ ZoneMinder-1.23.3_patch/src/zm_stream.cpp	2008-05-08 21:25:49.000000000 +0200
@@ -95,12 +95,15 @@
 Image *StreamBase::prepareImage( Image *image )
 {
     static int last_scale = 0;
+    static int last_rotate = 0;
     static int last_zoom = 0;
     static int last_x = 0;
     static int last_y = 0;
 
     if ( !last_scale )
         last_scale = scale;
+    if ( !last_rotate )
+        last_rotate = rotate;
     if ( !last_zoom )
         last_zoom = zoom;
 
@@ -141,6 +144,8 @@
     int last_send_image_width = (last_disp_image_width * last_act_mag ) / last_mag, last_send_image_height = (last_disp_image_height * last_act_mag ) / last_mag;
     Debug( 3, ( "Last send image width = %d, height = %d", last_send_image_width, last_send_image_height ));
 
+    Debug( 3, ( "Rotating by %d (former image width/height might be not correct)", rotate ));
+
     if ( mag != ZM_SCALE_BASE )
     {
         Debug( 3, ( "Magnifying by %d", mag ));
@@ -157,6 +162,12 @@
         }
     }
 
+    // former image width/height vars might get incorrect
+    if (rotate != 0)
+    {
+         image->Rotate( rotate );
+    }
+
     Debug( 3, ( "Real image width = %d, height = %d", image->Width(), image->Height() ));
 
     if ( disp_image_width < virt_image_width || disp_image_height < virt_image_height )
@@ -217,6 +228,7 @@
         image->Crop( last_crop );
     }
     last_scale = scale;
+    last_rotate = rotate;
     last_zoom = zoom;
     last_x = x;
     last_y = y;
@@ -235,6 +247,10 @@
     {
         image.Scale( scale );
     }
+    if ( rotate != 100 )
+    {
+        image.Rotate( rotate );
+    }
 #if HAVE_LIBAVCODEC
     if ( type == STREAM_MPEG )
     {
diff -U 3 -H -d -r -N -- ZoneMinder-1.23.3/src/zm_stream.h ZoneMinder-1.23.3_patch/src/zm_stream.h
--- ZoneMinder-1.23.3/src/zm_stream.h	2008-02-25 10:49:52.000000000 +0100
+++ ZoneMinder-1.23.3_patch/src/zm_stream.h	2008-05-08 21:50:27.000000000 +0200
@@ -57,7 +57,7 @@
     } DataMsg;
 
     typedef enum { MSG_CMD=1, MSG_DATA_WATCH, MSG_DATA_EVENT } MsgType;
-    typedef enum { CMD_NONE=0, CMD_PAUSE, CMD_PLAY, CMD_STOP, CMD_FASTFWD, CMD_SLOWFWD, CMD_SLOWREV, CMD_FASTREV, CMD_ZOOMIN, CMD_ZOOMOUT, CMD_PAN, CMD_SCALE, CMD_PREV, CMD_NEXT, CMD_SEEK, CMD_QUERY=99 } MsgCommand;
+    typedef enum { CMD_NONE=0, CMD_PAUSE, CMD_PLAY, CMD_STOP, CMD_FASTFWD, CMD_SLOWFWD, CMD_SLOWREV, CMD_FASTREV, CMD_ZOOMIN, CMD_ZOOMOUT, CMD_PAN, CMD_SCALE, CMD_PREV, CMD_NEXT, CMD_SEEK, CMD_QUERY=99, CMD_ROTATE } MsgCommand;
 
 protected:
     Monitor *monitor;
@@ -66,6 +66,7 @@
     const char *format;
     int replay_rate;
     int scale;
+    int rotate;
     int zoom;
     int maxfps;
     int bitrate;
@@ -117,6 +118,7 @@
         format = "";
         replay_rate = DEFAULT_RATE;
         scale = DEFAULT_SCALE;
+        rotate = 0;
         zoom = DEFAULT_ZOOM;
         maxfps = DEFAULT_MAXFPS;
         bitrate = DEFAULT_BITRATE;
@@ -155,6 +157,10 @@
     {
         scale = p_scale;
     }
+	void setStreamRotate( int p_rotate )
+    {
+        rotate = p_rotate;
+    }
 	void setStreamReplayRate( int p_rate )
     {
         replay_rate = p_rate;
Files ZoneMinder-1.23.3/src/zma and ZoneMinder-1.23.3_patch/src/zma differ
Files ZoneMinder-1.23.3/src/zmc and ZoneMinder-1.23.3_patch/src/zmc differ
Files ZoneMinder-1.23.3/src/zmf and ZoneMinder-1.23.3_patch/src/zmf differ
Files ZoneMinder-1.23.3/src/zmfix and ZoneMinder-1.23.3_patch/src/zmfix differ
Files ZoneMinder-1.23.3/src/zms and ZoneMinder-1.23.3_patch/src/zms differ
diff -U 3 -H -d -r -N -- ZoneMinder-1.23.3/src/zms.cpp ZoneMinder-1.23.3_patch/src/zms.cpp
--- ZoneMinder-1.23.3/src/zms.cpp	2008-02-25 10:49:52.000000000 +0100
+++ ZoneMinder-1.23.3_patch/src/zms.cpp	2008-05-08 21:51:29.000000000 +0200
@@ -60,6 +60,7 @@
 	int event_id = 0;
 	int frame_id = 1;
 	unsigned int scale = 100;
+	int rotate = 0;
 	unsigned int rate = 100;
 	unsigned int maxfps = 10;
 	unsigned int bitrate = 100000;
@@ -93,9 +94,9 @@
 		char temp_query[1024];
 		strncpy( temp_query, query, sizeof(temp_query) );
 		char *q_ptr = temp_query;
-		char *parms[16]; // Shouldn't be more than this
+		char *parms[17]; // Shouldn't be more than this
 		int parm_no = 0;
-		while( (parm_no < 16) && (parms[parm_no] = strtok( q_ptr, "&" )) )
+		while( (parm_no < 17) && (parms[parm_no] = strtok( q_ptr, "&" )) )
 		{
 			parm_no++;
 			q_ptr = NULL;
@@ -130,6 +131,8 @@
 				frame_id = strtoull( value, (char **)NULL, 10 );
 			else if ( !strcmp( name, "scale" ) )
 				scale = atoi( value );
+			else if ( !strcmp( name, "rotate" ) )
+				rotate = atoi( value );
 			else if ( !strcmp( name, "rate" ) )
 				rate = atoi( value );
 			else if ( !strcmp( name, "maxfps" ) )
@@ -241,6 +244,7 @@
 	{
         MonitorStream stream;
         stream.setStreamScale( scale );
+        stream.setStreamRotate( rotate );
         stream.setStreamReplayRate( rate );
         stream.setStreamMaxFPS( maxfps );
         stream.setStreamTTL( ttl );
@@ -281,6 +285,7 @@
     {
         EventStream stream;
         stream.setStreamScale( scale );
+        stream.setStreamRotate( rotate );
         stream.setStreamReplayRate( rate );
         stream.setStreamMaxFPS( maxfps );
         stream.setStreamMode( replay );
Files ZoneMinder-1.23.3/src/zmu and ZoneMinder-1.23.3_patch/src/zmu differ
