Index: /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionAPIConverter.pm
===================================================================
--- /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionAPIConverter.pm	(revision 37045)
+++ /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionAPIConverter.pm	(revision 37046)
@@ -44,5 +44,5 @@
 
 use utf8;
-use JSON qw( from_json );
+use JSON; # qw( from_json, encode_json );
 
 sub BEGIN {
@@ -128,46 +128,39 @@
     my $outhandle = $self->{'outhandle'};
     print $outhandle "----- GoogleVisionAPIConveter run_gv_convert -----\n";
-    # print STDERR "*****", $self->{'enable_document_ocr'}, "\n";
-
-    my @vision_type = (); # array containing target ocr / labelling type(s)
-
-    if ($self->{'enable_image_labelling'}) { push(@vision_type, "enable_image_labelling"); } 
-    if ($self->{'enable_image_ocr'})       { push(@vision_type, "enable_image_ocr");       }
-    if ($self->{'enable_document_ocr'})    { push(@vision_type, "enable_document_ocr");    } 
-
-    my $vision_type_length = @vision_type; # assigning scalar var to array returns length
-
-    if ($vision_type_length != 0) {
+
+    my @vision_types = (); # array containing target ocr / labelling type(s)
+
+    if ($self->{'enable_image_labelling'}) { push(@vision_types, "enable_image_labelling"); } 
+    if ($self->{'enable_image_ocr'})       { push(@vision_types, "enable_image_ocr");       }
+    if ($self->{'enable_document_ocr'})    { push(@vision_types, "enable_document_ocr");    } 
+
+    my $vision_types_length = scalar(@vision_types);
+
+    if ($vision_types_length != 0) {
        
         $self->init_cache_for_file($filename);
         my $cached_image_dir = $self->{'cached_dir'};
-	    # my $audio_root = $self->{'cached_file_root'};
+	# my $cached_image_root = $self->{'cached_file_root'};
 
         # my $filename_no_path = &File::Basename::basename($filename);
 
-        my $ofile = "google-vision-output.json";
-        my $ofilename = &FileUtils::filenameConcatenate($cached_image_dir,"google-vision-output.json");
         my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
         my $credentials_filename = &FileUtils::filenameConcatenate($collect_dir, "etc", $self->{'google_application_credentials'});
 
-        if ($vision_type_length == 1) {
-            my $vision_type_first = $vision_type[0];
-            my $vision_cmd = "vision.py --$vision_type_first --credentials \"$credentials_filename\" \"$filename\" \"$ofilename\"";
-
-            $self->run_vision($file, $filename, $ofile, $ofilename, $vision_cmd, $vision_type_first, $section, $doc_obj);
-        }
-	elsif ($vision_type_length == 2) {
-            my $vision_type_first = $vision_type[0];
-            my $vision_type_second = $vision_type[1];
-
-            my $ofilename_first = &FileUtils::filenameConcatenate($cached_image_dir, $vision_type_first . "-google-vision-output.json");
-            my $ofilename_second = &FileUtils::filenameConcatenate($cached_image_dir, $vision_type_second . "-google-vision-output.json");
-
-            my $vision_cmd_1 = "vision.py --$vision_type_first --credentials \"$credentials_filename\" \"$filename\" \"$ofilename_first\"";
-            my $vision_cmd_2 = "vision.py --$vision_type_second --credentials \"$credentials_filename\" \"$filename\" \"$ofilename_second\"";
-
-            $self->run_vision($file, $filename, $ofile, $ofilename_first, $vision_cmd_1, $vision_type_first, $section, $doc_obj);
-            $self->run_vision($file, $filename, $ofile, $ofilename_second, $vision_cmd_2, $vision_type_second, $section, $doc_obj);
-        } 
+	for my $vision_type (@vision_types) {
+
+	    my $ofile = "${vision_type}-google-vision-output.json";
+	    my $ofilename = &FileUtils::filenameConcatenate($cached_image_dir,$ofile);
+
+	    my $vision_cmd = "vision.py --$vision_type --credentials \"$credentials_filename\" \"$filename\" \"$ofilename\"";
+
+            $self->run_vision($file, $filename, $ofile, $ofilename, $vision_cmd, $vision_type, $doc_obj,$section);
+
+	    if ($vision_type eq "enable_document_ocr") {
+		my $gv_dococr_rec = { 'filename' => $ofilename, 'section' => $section };
+		
+		push(@{$self->{'gv-dococr-json-filename-recs'}}, $gv_dococr_rec);
+	    }	    
+	}
     }
 
@@ -175,8 +168,59 @@
 }
 
-sub run_vision {
-    use Data::Dumper;
-    my $self = shift (@_);
-    my ($file, $filename, $ofile, $ofilename, $vision_cmd, $vision_type, $section, $doc_obj) = @_;
+sub gv_ocr_bounding_box_rect
+{
+    my $self = shift (@_);
+    my ($gv_block,) = @_;
+
+    my $bbox_rect = undef;
+    
+    my $gv_boundingBox = $gv_block->{'boundingBox'};
+
+    my $gv_vertices = $gv_boundingBox->{'vertices'};
+    my $gv_num_vertices = scalar(@$gv_vertices);
+
+    if ($gv_num_vertices > 0) {
+	# print STDERR "**** gs_vertices[0] = ", JSON::encode_json($gv_vertices->[0]), "\n";
+
+	# Discovered that sometimes the 'x' value in the 'vertices' structure is not defined
+	# So can't rely on picking up $gv_vertices->[0 for 'x' and 'y'
+	# start off with 'undef' and test for !defined in for-loop
+
+	my $min_x = undef;
+	my $min_y = undef;
+	my $max_x = undef;
+	my $max_y = undef;
+
+	
+	for (my $v=0; $v<$gv_num_vertices; $v++) {
+	    my $x = $gv_vertices->[$v]->{'x'};
+	    my $y = $gv_vertices->[$v]->{'y'};
+
+	    if (defined $x) {
+		$min_x = $x if (!defined $min_x || ($x < $min_x));
+		$max_x = $x if (!defined $max_x || ($x > $max_x));
+	    }
+
+	    if (defined $y) {
+		$min_y = $y if (!defined $min_y || ($y < $min_y));
+		$max_y = $y if (!defined $max_y || ($y > $max_y));
+	    }
+	}
+    
+	my $x_org = $min_x;
+	my $y_org = $min_y;
+	my $x_dim = $max_x - $min_x +1;
+	my $y_dim = $max_y - $min_y +1;
+    
+	$bbox_rect = { "x_org" => $x_org, "y_org" => $y_org, "x_dim" => $x_dim, "y_dim" => $y_dim};
+    }
+    
+    return $bbox_rect;
+}
+
+sub run_vision
+{
+    my $self = shift (@_);
+    my ($file, $filename, $ofile, $ofilename, $vision_cmd, $vision_type, $doc_obj,$section) = @_;
 
     my $vision_regenerated;
@@ -184,6 +228,8 @@
     my $vision_error;
 
-    my $print_info = { 'message_prefix' => "GoogleVisionAPI",
-        'message' => "Sending $file to GoogleVisionAPI using vision.py" };
+    my $print_info = {
+	'message_prefix' => "GoogleVisionAPI",
+	'message'        => "Sending $file to GoogleVisionAPI using vision.py"
+    };
 
     ($vision_regenerated,$vision_result,$vision_error)
@@ -194,11 +240,10 @@
     # => add in section number as part of the file name to avoid clashes
     
-    my $gv_assoc_prefix = $vision_type;
-    $gv_assoc_prefix =~ s/^enable_/gv_/;
-
     my $section_file_suffix = $section;
     $section_file_suffix =~ s/\./_/g;
 
-    my $assoc_ofile = $gv_assoc_prefix.$ofile;
+    my $assoc_ofile = $ofile;
+    $assoc_ofile =~ s/^enable_/gv_/;
+    $assoc_ofile =~ s/-google-vision//;
     $assoc_ofile =~ s/\.(.*?)$/$section_file_suffix.$1/;
 	
@@ -212,20 +257,21 @@
     };
 
-    my $decoded_json = from_json($json_text); 
+    my $decoded_json = JSON::from_json($json_text);
+    
     my $ocr_text;
     if ($vision_type eq "enable_document_ocr" || $vision_type eq "enable_image_ocr") {
-        $ocr_text = $decoded_json->{textAnnotations}[0]{description}; # access full ocr content
-        $doc_obj->add_utf8_text( $section, $ocr_text); # append text to section
-
-        my $blocks = $decoded_json->{fullTextAnnotation}{pages}[0]{blocks};
+        $ocr_text = $decoded_json->{'textAnnotations'}[0]{'description'}; # access full ocr content
+        $doc_obj->add_utf8_text($section, $ocr_text); # append text to section
+
+        my $blocks = $decoded_json->{'fullTextAnnotation'}{'pages'}[0]{'blocks'};
         my %text_and_language;
 
-        foreach my $block (@{ $blocks }) {
-            foreach my $paragraph (@{ $block->{paragraphs} }) {
-                foreach my $word (@{ $paragraph->{words} }) {
-                    my $detected_language = $word->{property}{detectedLanguages}[0]{languageCode} || "no_lang";
+        foreach my $block (@{$blocks}) {
+            foreach my $paragraph (@{$block->{'paragraphs'}}) {
+                foreach my $word (@{$paragraph->{'words'}}) {
+                    my $detected_language = $word->{'property'}{'detectedLanguages'}[0]{'languageCode'} || "no_lang";
                     my $word_text = "";
-                    foreach my $letter (@{ $word->{symbols} }) {
-                        $word_text .= $letter->{text};
+                    foreach my $letter (@{$word->{'symbols'}}) {
+                        $word_text .= $letter->{'text'};
                     }
                     $text_and_language{$detected_language} .= $word_text . " "; 
@@ -235,5 +281,5 @@
 	
         for (keys %text_and_language) {
-            $doc_obj->add_utf8_metadata ($section, "z_" . $_, $text_and_language{$_});
+            $doc_obj->add_utf8_metadata($section, "z_" . $_, $text_and_language{$_});
         }
 
@@ -244,48 +290,304 @@
 	    $assoc_json_metaname .= "DocumentOCRJSON";
 
-	    $doc_obj->add_utf8_metadata ($section, "GVDocumentOCRJSON",$assoc_ofile);
+	    $doc_obj->add_utf8_metadata($section, "GVDocumentOCRJSON",$assoc_ofile);
 	}
 	else {
-	    # $vision_type eq "enable_image_ocr")
+	    # $vision_type eq "enable_image_ocr"
 	    $assoc_json_metaname .= "ImageOCRJSON";
 
-	    $doc_obj->add_utf8_metadata ($section, "GVImageOCRJSON",$assoc_ofile);
-	}
-
-	$doc_obj->add_utf8_metadata ($section, $assoc_json_metaname, 1);
+	    $doc_obj->add_utf8_metadata($section, "GVImageOCRJSON",$assoc_ofile);
+	}
+
+	$doc_obj->add_utf8_metadata($section, $assoc_json_metaname, 1);	
     }
     elsif ($vision_type eq "enable_image_labelling") {
-        $ocr_text = $decoded_json->{labelAnnotations};	
-        foreach my $label (@{ $ocr_text }) {
+        $ocr_text = $decoded_json->{'labelAnnotations'};	
+        foreach my $label (@{$ocr_text}) {
             # write to metadata : 'description'='Book' 'score'='0.9' 'topicality'='0.9' 'mid'='/m/0123'
-            $doc_obj->add_utf8_metadata ($section, "description", $label->{description});
-            $doc_obj->add_utf8_metadata ($section, "score", $label->{score});
-            $doc_obj->add_utf8_metadata ($section, "topicality", $label->{topicality});
-            $doc_obj->add_utf8_metadata ($section, "mid", $label->{mid});
+            $doc_obj->add_utf8_metadata($section, "description", $label->{'description'});
+            $doc_obj->add_utf8_metadata($section, "score",       $label->{'score'});
+            $doc_obj->add_utf8_metadata($section, "topicality",  $label->{'topicality'});
+            $doc_obj->add_utf8_metadata($section, "mid",         $label->{'mid'});
 
 	    # write to metadata : 'descriptions'='Book' 'Book_score'='0.9' 'Book_topicality'='0.9' 'Book_mid'='/m/0123' 
-            $doc_obj->add_utf8_metadata ($section, "descriptions", $label->{description});
-            $doc_obj->add_utf8_metadata ($section, $label->{description} . "_score", $label->{score});
-            $doc_obj->add_utf8_metadata ($section, $label->{description} . "_topicality", $label->{topicality});
-            $doc_obj->add_utf8_metadata ($section, $label->{description} . "_mid", $label->{mid});
+            $doc_obj->add_utf8_metadata($section, "descriptions", $label->{'description'});
+            $doc_obj->add_utf8_metadata($section, $label->{'description'} . "_score", $label->{'score'});
+            $doc_obj->add_utf8_metadata($section, $label->{'description'} . "_topicality", $label->{'topicality'});
+            $doc_obj->add_utf8_metadata($section, $label->{'description'} . "_mid", $label->{'mid'});
 
         }
 	
-	$doc_obj->add_utf8_metadata ($section, "HasGoogleVisionImageLabellingJSON", 1);
-	$doc_obj->add_utf8_metadata ($section, "GVImageLabellingJSON",$assoc_ofile);
-
-    }
+	$doc_obj->add_utf8_metadata($section, "HasGoogleVisionImageLabellingJSON", 1);
+	$doc_obj->add_utf8_metadata($section, "GVImageLabellingJSON",$assoc_ofile);
+
+    }
+}
+
+sub start_openannotation_list
+{
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    my $OID = $doc_obj->get_OID();
+
+    my $openannotation_list = {
+        "\@context" => "http://www.shared-canvas.org/ns/context.json",
+	# "\@id"      => "https://iiif.harvardartmuseums.org/manifests/object/299843/list/47174896", 
+	"\@id"      => "${OID}/openannotation-list.json",  # #### **** make full URL to be unique? or greenstone3:site:collect:OID ??
+	"\@type"    => "sc:AnnotationList",
+	"resources" => []
+    };
+
+    $self->{'openannotation-list'} = $openannotation_list;
+}
+
+
+    
+sub convert_gvocr_to_openannotation_resource
+{
+    my $self = shift (@_);
+    my ($gv_blocks, $doc_obj, $section) = @_;
+
+    my $OID = $doc_obj->get_OID();
+    my $OID_with_section = ($section ne "") ? "${OID}_$section" : $OID;
+    $section = 1 if ($section eq ""); # occurs when the document is a single image
+    
+	
+    # Example Open Annotation resource (for single annotation):
+#      {
+#             "@context": "http://iiif.io/api/presentation/2/context.json",
+#             "@id": "https://iiif.harvardartmuseums.org/annotations/9641482",
+#             "@type": "oa:Annotation",
+#             "motivation": [
+#                 "oa:commenting"
+#             ],
+#             "on": {
+#                 "@type": "oa:SpecificResource",
+#                 "full": "https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174896",
+#                 "selector": {
+#                     "@type": "oa:FragmentSelector",
+#                     "value": "xywh=622,591,642,940"
+#                 },
+#                 "within": {
+#                     "@id": "https://iiif.harvardartmuseums.org/manifests/object/299843",
+#                     "@type": "sc:Manifest"
+#                 }
+#             },
+#             "resource": [
+#                 {
+#                     "@type": "dctypes:Text",
+#                     "chars": "<p>age: 35-52<br/>gender: Female(66.337677%)<br/>CALM: 55.438412%<br/>CONFUSED: 3.949288%<br/>SURPRISED: 2.33092%<br/>DISGUSTED:
+# 0.545727%<br/>HAPPY: 1.549943%<br/>ANGRY: 2.082294%<br/>SAD: 34.103416%<br/></p><p>Generated by AWS Rekognition</p>",
+#                     "format": "text/html"
+#                 }
+#             ]
+#         },
+
+    my $self_openannotation_resources = $self->{'openannotation-list'}->{'resources'};
+
+    my $block_i = 0;
+    
+    foreach my $block (@{$gv_blocks}) {
+	$block_i++;
+	
+	my $openannotation_resource = {
+	    "\@context"  => "http://iiif.io/api/presentation/2/context.json",
+	    # "\@id"       => "https://iiif.harvardartmuseums.org/annotations/9641482",
+	    "\@id"       => "${OID_with_section}/annotation/gv-block-$block_i", # #### **** make full URL to be unique? or greenstone3:site:collect:OID ??
+	    "\@type"     => "oa:Annotation",
+	    "motivation" => [ "oa:commenting" ]
+	};
+	
+
+	my $bbox_rect = $self->gv_ocr_bounding_box_rect($block);
+	my $bb_x_org = $bbox_rect->{'x_org'};
+	my $bb_y_org = $bbox_rect->{'y_org'};
+	my $bb_x_dim = $bbox_rect->{'x_dim'};
+	my $bb_y_dim = $bbox_rect->{'y_dim'};
+	
+	my $openannotation_on = {
+	    "\@type" => "oa:SpecificResource",
+	    # "full"   => "https://iiif.harvardartmuseums.org/manifests/object/299843/canvas/canvas-47174896", 
+	    "full"   => "${OID}/canvas/$section", # doc id + /canvas + page-i/sect # #### **** make full URL to be unique? or greenstone3:site:collect:OID ??
+	    "selector" => {
+		"\@type" => "oa:FragmentSelector",
+		"value"  => "xywh=${bb_x_org},${bb_y_org},${bb_x_dim},${bb_y_dim}"
+	    },
+	    "within" => {
+		#"\@id"   => "https://iiif.harvardartmuseums.org/manifests/object/299843", 
+		"\@id"   => "${OID_with_section}/manifest", # #### **** make full URL to be unique? or greenstone3:site:collect:OID... ??
+		"\@type" => "sc:Manifest"
+	    }
+	};
+	$openannotation_resource->{'on'} = $openannotation_on;
+	    
+
+	my $block_text_html = "";
+	
+	foreach my $paragraph (@{$block->{'paragraphs'}}) {
+	    my $para_text = "";
+	    
+	    foreach my $word (@{$paragraph->{'words'}}) {
+		my $word_text = "";
+		
+		foreach my $letter (@{$word->{'symbols'}}) {
+		    $word_text .= $letter->{'text'};
+		}
+
+		$para_text .= " " if $para_text ne "";
+		$para_text .= $word_text;
+	    }
+
+	    $block_text_html .= "<p>\n$para_text\n</p>\n\n";
+	}
+	    
+	my $openannotation_inner_resource = [{
+		"\@type"  => "dctypes:Text",
+		"chars"   => "$block_text_html",
+		"format"  => "text/html"
+	}];
+
+	$openannotation_resource->{'resource'} = $openannotation_inner_resource;
+
+	push(@$self_openannotation_resources,$openannotation_resource);	    
+    }
+}
+
+
+sub convert_and_append_openannotation_resources
+{
+    my $self = shift (@_);
+    my ($gv_dococr_json_filename, $doc_obj, $section) = @_;
+
+
+    # Read in JSON file
+    my $json_text = do { 
+	open(my $json_fh, "<:encoding(UTF-8)", $gv_dococr_json_filename)
+	    or die("Can't open \"$gv_dococr_json_filename\": $!\n");
+	local $/;
+	<$json_fh>
+    };
+    
+    my $decoded_json = JSON::from_json($json_text);
+    
+    my $gv_blocks = $decoded_json->{'fullTextAnnotation'}->{'pages'}->[0]->{'blocks'};
+
+    $self->convert_gvocr_to_openannotation_resource($gv_blocks, $doc_obj, $section);
+}
+
+
+
+sub end_openannotation_list
+{
+    my $self = shift (@_);
+    my ($doc_obj,$json_ofilename) = @_;
+
+    my $ret_status = 1;
+    
+    if (!open(JOUT, "> $json_ofilename")) {
+	print STDERR "Error: Failed save Open Annotation List JSON to \"$json_ofilename\":\n    $!\n";
+        $ret_status = 0;
+    }
+    else {
+	binmode(JOUT, ":utf8");
+	
+	my $openannotation_list = $self->{'openannotation-list'};
+	my $openannotation_list_json_text = JSON::encode_json($openannotation_list);
+	
+	print JOUT $openannotation_list_json_text;
+	close JOUT;
+	
+    }    
+    
+    $self->{'openannotation-list'} = undef;
+    
+    return $ret_status;
+}
+
+sub openannotation_list_associate_json
+{
+    my $self = shift (@_);
+    my ($doc_obj, $gv_dococr_json_filename_recs) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    
+    # Guaranteed to have at least one value in gv_dococr_json_filename_recs
+    #
+    # Legacy code used to have a '\d+' just before the '.json' reflecting page/section number
+    # Keep this in the regular expression, just in case,
+    # 
+    my ($gv_dococr_filename_root) = ($gv_dococr_json_filename_recs->[0]->{'filename'} =~ m/^(.+)(?:\d+)?\.json$/);
+
+    # slight of hand so new directory spot in cache_dir picked out is where we want it!
+    $gv_dococr_filename_root .= "/";
+    
+    my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
+    my $toplevel_cached_dir = &FileUtils::filenameConcatenate($collect_dir,"cached");
+    
+    $self->init_cache_for_file($gv_dococr_filename_root);
+    my $cached_dir = $self->{'cached_dir'};
+
+    my $assoc_openannotation_json_ofile = "openannotation-list.json";
+    my $cached_openannotation_json_ofilename = &FileUtils::filenameConcatenate($cached_dir,$assoc_openannotation_json_ofile);    
+
+    my $needs_json_regen = 0;
+
+    if (!-f $cached_openannotation_json_ofilename) {
+	$needs_json_regen = 1;
+    }
+    else {
+	for my $gv_json_filename_rec (@$gv_dococr_json_filename_recs) {
+	    my $gv_json_filename = $gv_json_filename_rec->{'filename'};
+	    if (-M $gv_json_filename > -M $cached_openannotation_json_ofilename) {
+		$needs_json_regen = 1;
+		last;
+	    }
+	}
+    }
+
+    my $saved_ok = 1;
+    
+    if ($needs_json_regen) {
+
+	print $outhandle "  OpenAnnotation-List: Generating $cached_openannotation_json_ofilename\n";
+	
+	$self->start_openannotation_list($doc_obj);
+
+	for my $gv_json_filename_rec (@$gv_dococr_json_filename_recs) {
+	    my $gv_json_filename = $gv_json_filename_rec->{'filename'};
+	    my $section = $gv_json_filename_rec->{'section'};
+	    $self->convert_and_append_openannotation_resources($gv_json_filename, $doc_obj,$section);
+	}
+	
+	$saved_ok = $self->end_openannotation_list($doc_obj,$cached_openannotation_json_ofilename);
+    }
+    
+    if ($saved_ok) {
+	print $outhandle "  OpenAnnotation-List: Cached file $cached_openannotation_json_ofilename already exists\n";
+	
+	my $top_section = $doc_obj->get_top_section();
+	$doc_obj->associate_file($cached_openannotation_json_ofilename,$assoc_openannotation_json_ofile,"application/json",$top_section);
+    }
+
+    return $saved_ok;
+}
+
+sub opt_run_gen_openannotation
+{    
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    my $gv_dococr_json_filename_recs = $self->{'gv-dococr-json-filename-recs'};
+    my $num_gv_dococr_json_filename_recs = scalar(@$gv_dococr_json_filename_recs);
+
+    my $ret_val_ok = 1;
+    
+    if ($num_gv_dococr_json_filename_recs > 0) {
+	$ret_val_ok = $self->openannotation_list_associate_json($doc_obj,$gv_dococr_json_filename_recs);	
+    }
+
+    return $ret_val_ok;
 }
 
 1;
 
-
-
-
-
-
-
-
-
-
-
Index: /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionImagePlugin.pm
===================================================================
--- /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionImagePlugin.pm	(revision 37045)
+++ /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionImagePlugin.pm	(revision 37046)
@@ -82,8 +82,24 @@
     my $utf8_filename_no_path = $self->filepath_to_utf8($filename_no_path);
     my $url_encoded_filename = &util::rename_file($utf8_filename_no_path, $self->{'file_rename_method'});
+
+    $self->{'gv-dococr-json-filename-recs'} = [];
+
+    # The following also builds up the openanotation_list 'resources' array    
+    $self->run_gv_convert($filename_full_path,$url_encoded_filename,$doc_obj);
+
+    $self->SUPER::process(@_);
+}
+
+sub post_process_doc_obj {
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $ret_val_ok = $self->SUPER::post_process_doc_obj(@_);
     
-    $self->run_gv_convert($filename_full_path,$url_encoded_filename,$doc_obj);
+    if ($ret_val_ok) {
+	$ret_val_ok = $self->opt_run_gen_openannotation($doc_obj);
+    }
     
-    $self->SUPER::process(@_);
+    return $ret_val_ok;
 }
 
Index: /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionPagedImagePlugin.pm
===================================================================
--- /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionPagedImagePlugin.pm	(revision 37045)
+++ /gs3-extensions/structured-image/trunk/perllib/plugins/GoogleVisionPagedImagePlugin.pm	(revision 37046)
@@ -86,4 +86,17 @@
 
 
+sub init_new_doc_item
+{    
+    my $self = shift (@_);
+    my ($filename_full_path, $processor, $metadata) = @_;
+
+    my $doc_obj = $self->SUPER::init_new_doc_item(@_);
+
+    $self->{'gv-dococr-json-filename-recs'} = [];
+    
+    return $doc_obj;    
+}
+
+
 sub process_image {
     my $self = shift(@_);
@@ -94,7 +107,21 @@
     
     $self->run_gv_convert($filename_full_path,$url_encoded_filename,$doc_obj,$section);
-
+    
     return $self->SUPER::process_image(@_);
 }
 
+sub post_process_doc_obj {
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $ret_val_ok = $self->SUPER::post_process_doc_obj(@_);
+
+    if ($ret_val_ok) {
+	$ret_val_ok = $self->opt_run_gen_openannotation($doc_obj);
+    }
+    
+    return $ret_val_ok;
+}
+
+
 1;
