/*
** MUPage_Images.c
**
** Auxiliary functions for MUPage.c
**
** Oct2020 - ABU fecit
*/

#include "asprintf.h"   // WARNING: must be declared BEFORE <stdio.h>
#include "xpdf_extension.h"
#include "MUPage_Images.h"


 // On error return NULL ( error message saved in interp's result)
 // this is safe from fz-exceptions 
Tcl_Obj* mu_image_extract( Tcl_Interp* interp, fz_context* ctx, pdf_document* doc, pdf_obj* imDict, int useAlpha, const char*imID, const char* imName, const char* filenameWithoutExt) {
	char* filename = NULL;
	fz_image* image = NULL;
	
	fz_var(filename);
	fz_var(image);
	fz_try(ctx) {
		image = pdf_load_image(ctx,doc,imDict);
		
		int imType = xfz_image_type(ctx,image);
		char* ext;
		if (imType == FZ_IMAGE_JPEG) {
			ext = "jpg";
		} else {
			ext = "png";
		}
		asprintf(&filename,"%s.%s", filenameWithoutExt, ext);
		
		switch (imType) {
		  case FZ_IMAGE_JPEG:
			xfz_image_savejpeg(ctx, image, filename);
			break;
		  case FZ_IMAGE_PNG:
			xfz_image_savepng(ctx,image,useAlpha,filename);
			break;
		  default: {
			fz_throw(ctx, FZ_ERROR_GENERIC, "unknown image type");
			}
		}
	} fz_always(ctx) {
		if (image)  fz_drop_image(ctx,image);
	} fz_catch(ctx) {
		free(filename);
		Tcl_SetObjResult(interp, Tcl_NewStringObj(fz_caught_message(ctx),-1));
		return NULL;
	}
	
	Tcl_Obj * listObj = Tcl_NewListObj(0,NULL);
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(imID,-1));
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(imName,-1));
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(filename,-1));
	
	free(filename);
	return listObj;
}




 // return a list ...
 // load some imageattributes (without loading the image)
 
  // On error return NULL ( error message saved in interp's result)
  // this is safe from fz-exceptions
Tcl_Obj* mu_image_info( Tcl_Interp* interp, fz_context* ctx, pdf_obj* imDict, const char*imID) {
	int im_bpc = pdf_to_int(ctx, pdf_dict_geta(ctx, imDict, PDF_NAME(BitsPerComponent), PDF_NAME(BPC)));
	if (im_bpc == 0)  im_bpc = 8;
	
	 // code grabbed from tools/pdfinfo.c
	pdf_obj *altcolorSpaceObj = NULL;
	pdf_obj *colorSpaceObj = pdf_dict_geta(ctx, imDict, PDF_NAME(ColorSpace), PDF_NAME(CS));
	if (pdf_is_array(ctx, colorSpaceObj)) {
		pdf_obj *origCsObj = colorSpaceObj;
		colorSpaceObj = pdf_array_get(ctx, origCsObj, 0);
		if (pdf_name_eq(ctx, colorSpaceObj, PDF_NAME(DeviceN)) || pdf_name_eq(ctx, colorSpaceObj, PDF_NAME(Separation))) {
			altcolorSpaceObj = pdf_array_get(ctx, origCsObj, 2);
			if (pdf_is_array(ctx, altcolorSpaceObj))
				altcolorSpaceObj = pdf_array_get(ctx, altcolorSpaceObj, 0);
			}
	}
	
	int imWidth = pdf_to_int(ctx, pdf_dict_get(ctx, imDict, PDF_NAME(Width)));
	int imHeight= pdf_to_int(ctx, pdf_dict_get(ctx, imDict, PDF_NAME(Height)));
	int imHasMask = (pdf_dict_geta(ctx, imDict, PDF_NAME(SMask), PDF_NAME(Mask)) ? 1 : 0);
	
	Tcl_Obj *listObj = Tcl_NewListObj(0,NULL);						
	
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(imID,-1));
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(imWidth));
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(imHeight));
	 // print colorspace (and altcolorspace if not NULL)
	if ( altcolorSpaceObj == NULL ) {
		Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(pdf_to_name(ctx, colorSpaceObj),-1));
	} else {
		Tcl_Obj *csListObj = Tcl_NewListObj(0,NULL);
		Tcl_ListObjAppendElement(interp, csListObj, Tcl_NewStringObj(pdf_to_name(ctx, colorSpaceObj),-1));
		Tcl_ListObjAppendElement(interp, csListObj, Tcl_NewStringObj(pdf_to_name(ctx, altcolorSpaceObj),-1));
		Tcl_ListObjAppendElement(interp, listObj, csListObj);
	}
	 // number of color components can be inferred from colorspace
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(im_bpc));
	Tcl_ListObjAppendElement(interp, listObj, Tcl_NewBooleanObj(imHasMask));
	return listObj;
}
