TagGroupGetTagType returns wrong type - dm-script

Basically this is the specific question for my older question which I just can't solve.
I was given an example image for my development. This image contains a (I guess representative) TagGrop that displays the information about how the image is created.
My problem is, that TagGroupGetTagType() of the elements of this TagGroup returns 3 for elements that are TagGroups itself. But TagGroups have the type 0 (confirmed by myself and #BmyGuest in the linked question). The following image shows the output of my example script together with the tag editor dialog. As one can see that every element has the type 3, including TagGroups like Acquision or others.
The image above has been created with the following script:
clearResults();
image img;
img.GetFrontImage();
TagGroup tg = img.ImageGetTagGroup();
TagGroupOpenBrowserWindow(tg, 0);
for(number i = 0; i < tg.TagGroupCountTags(); i++){
String label = tg.TagGroupGetTagLabel(i);
number type = tg.TagGroupGetTagType(i, 0);
result("Index " + label + " has type " + type + "\n");
}
What am I doing wrong? Why does this not work? Is there any way to get the correct type?
This may be related to the file so I created an example file which is missing some of the indices (for protecting the privacy of the people who gave me this file). The posted output is in fact created with this file. So the same problem occurres. This file can be downloaded from https://www.file-upload.net/download-14020685/example.dm4.html.
(For anyone who doesn't like to download files from random pages you can get the base64 encoded file contents here: https://cutpaste.online/notes.html?id=xcix7x9e9sHxMFwF3e5h)

A confirmation & Workaround
Using your script and provided file, I can exactly reproduce the result.
Moreover, if I run the following script (in GMS 3.4):
image img := RealImage("Test",4,10,10)
taggroup newTG = NewTagGroup()
newTG.TagGroupSetTagAsString("Test","oh")
img.imagegettaggroup().TagGroupSetTagAsTagGroup("TG",newTG)
img.ShowImage()
And then run your script, I get:
Index GMS Version has type 0
Index TG has type 0
However, if I save the file and then open it up again and run your script, I suddenly get:
Index GMS Version has type 3
Index TG has type 3
So, something has clearly changed and is off. I tried some older data (all saved with GMS 3.x) and I always get a type 3 for TagGroups. I could not find data saved by GMS 2.x or GMS 1.x but would assume either or both would return type 0.
I've also noticed that the command TagGroupGetTagTypeLength returns 0 before saving, but 1 for the loaded image, and I think that might be related.
But there is a workaround you can use, which might solver your actual question.
For TagGroups (and TagLists) you can replace your check for the type by an actual attempt to get the tag as a TagGroup, as in:
clearResults();
image img;
img.GetFrontImage();
TagGroup tg = img.ImageGetTagGroup();
TagGroupOpenBrowserWindow(tg, 0);
for(number i = 0; i < tg.TagGroupCountTags(); i++){
String label = tg.TagGroupGetTagLabel(i);
number typeL = tg.TagGroupGetTagTypeLength(i);
number type = tg.TagGroupGetTagType(i, 0);
result("Index " + label + " has " + typeL + " types. Type = " + type + "\n");
TagGroup tgtest
if ( tg.TagGroupGetIndexedTagAsTagGroup(i,tgtest) )
Result("\tIt is as TagGroup (or TagList)!\n")
}

Related

Pentaho JsonInput GET fields

I'm trying to use PDI to read data from an API (json) and now I'm simply trying to use json input to get a few specific fields but the get fields button on the input step gives me.
ERROR (version 8.3.0.0-371, build 8.3.0.0-371 from 2019-06-11 11.09.08 by buildguy) : Index 1 out of bounds for length 1
all the steps execute fine, and produce data - just not the json input step doesn't wnat to give me the fields option! - I've tired the text file and json oput and both write valid json so IDK whats going on....
PS. this is my first time using PDI
ISSUE 2:
It looks like PDI uses jayway for its json path parsing so I've been using this site https://jsonpath.herokuapp.com/ jayway selection which gives me my expected path. When I put that into the 'fields' of the json input dialog I only get the FIRST instance of that path value vs it actually parsing the json and giving me every instance, and can't figure out why though I assume it has something to do with PDI's row based view on things but I also don't know how to get it to understand that its json and it should be giving me back all values that match that path.
UPDATE 1:
I've been looking at this https://forums.pentaho.com/threads/135882-Parsing-JSON-data-without-knowing-field-names/ it seems like this Modified Java Script Value step might be the way to go. Will continue testing.
UPDATE 2
OK - Used the MJSV as posted above along with a select fields step and finally able to get the key's
var obj = JSON.parse(mydata);
var keys = Object.keys(obj);
for (var i = 0; i < Object.keys(obj).length; i++) {
var row = createRowCopy(getOutputRowMeta().size());
var idx = getInputRowMeta().size();
row[idx++] = keys[i];
putRow(row);
}
trans_Status = SKIP_TRANSFORMATION;

Reproducible screenshots with Selenium and Firefox

I use Selenium to automate some GUI tests using the firefox web driver.
It occurred to me that it would be also make sense to create screenshots during the run of the tests to use those in the manual.
The screens of my application are relatively static - no timestamps visible and so on. So my expectation would be, if I create a screenshot from lets say the start page, navigate later to the start page again, the screenshots should be identical. Also if I run the test twice, the screenshot of the start page should be identical between both runs.
I save the screenshots as PNG, I even process the screenshots (save without date) before saving them, so that the files should be really identical.
Nevertheless, if I compare the pictures with each other (e.g. subtract them from each other), there are minor differences between them (not visible to the naked eye), some faint lines at the border of tables, or around fonts.
My question:
1) Why are there differences at all?
2) What could be the easiest way to ensure that the screenshots are identical? (what kind of post processing could I do)
PS: I also tried to change the renderer from skia to windows to cairo, but although the differences are slightly different, it still doesn't solve the problem.
How do you save the images ?
In ruby I was using something like this ?
def take_screenshot(image_id)
scenario = Zpg::HooksHelper::FeatureHelper.scenario_name
Dir.mkdir('output', 0o777) unless File.directory?('output')
Dir.mkdir('output/screenshots', 0o777) unless File.directory?('output/screenshots')
screenshot = "./output/screenshots/#{image_id}#{scenario.tr(' ', '_').gsub(/[^0-9A-Za-z_]/, '')}.png"
if page.driver.browser.respond_to?(:save_screenshot)
page.driver.browser.save_screenshot(screenshot)
else
save_screenshot(screenshot)
end
FileUtils.chmod(0o777, screenshot)
end
And I was checking the image diff
# return[hash]
def image_diff(imageid_1 = nil, _imageid_2 = nil)
scenario = Zpg::HooksHelper::FeatureHelper.scenario_name
if imageid_1.class != Integer
image_1 = "./features/support/data/images/#{Zpg.brand}/#{imageid_1}.png"
image_2 = "./output/screenshots/#{_imageid_2}#{scenario.tr(' ', '_').gsub(/[^0-9A-Za-z_]/, '')}.png"
else
image_1 = "./output/screenshots/#{imageid_1}#{scenario.tr(' ', '_').gsub(/[^0-9A-Za-z_]/, '')}.png"
image_2 = "./output/screenshots/#{_imageid_2}#{scenario.tr(' ', '_').gsub(/[^0-9A-Za-z_]/, '')}.png"
end
images = [
ChunkyPNG::Image.from_file(image_1),
ChunkyPNG::Image.from_file(image_2)
]
diff = []
images.first.height.times do |y|
images.first.row(y).each_with_index do |pixel, x|
diff << [x, y] unless pixel == images.last[x, y]
end
end
puts "pixels (total): #{images.first.pixels.length}"
puts "pixels changed: #{diff.length}"
puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%"
# init empty hash
diff_hash = {}
# return pixels changed number
diff_hash[:pixels_changed] = diff.length
# return pixels changed percentage
diff_hash[:pixels_changed_percentage] = (diff.length.to_f / images.first.pixels.length) * 100
# return diff hash
diff_hash
end
you can get different results if the browser DOM is not 100% loaded . I would try to have a threshold in which I would expect my image to be .
There is a very good project here in .Net https://www.codeproject.com/Articles/374386/Simple-image-comparison-in-NET which you can convert in any language you want.

Karate: How to use a Javascript function from a DIFFERENT feature file

I have created a feature file that will contain lots of javascript functions.
From within a DIFFERENT feature file I want to use ONE of those functions (and pass in a value).
How do I do this please?
My feature file is called SystemSolentraCustomKarateMethods.feature
Here is the current content (it currently contains just one function):
Feature: System Solentra Status Test
Background:
* def checkreturneddatetimeiscorrect =
#The following code compares the passed in datetime with the current systemdatetime and
#makes sure they are within 2 seconds of each other
"""
function(datetime) {
var datenow = new Date();
karate.log("***The Date Now = " + datenow.toISOString() + " ***");
var timenow = datenow.getTime();
karate.log("***The Time Now in Milliseconds = " + timenow+ " ***");
karate.log("***The Passedin Date = " + datetime + " ***");
var passedintime = new Date();
passedintime = Date.parse(datetime);
karate.log("***The Passed in Time = " + passedintime+ " ***");
var difference = timenow - passedintime;
karate.log("***The Time Difference = " + difference + " milliseconds ***");
return (difference < 2000)
}
"""
Thanks Peter I have figured out how to do this now.
(1) The feature file that contains the functions MUST have the Feature, Background and Scenario tags - even if your file does NOT contain any scenarios. (*see my example file below)
(2) In the feature file that you are calling FROM add the following code to the Background section:
* call read('yourfilename.feature')
(3) You can now use the functions within the called feature file
Here is the structure of the feature file I am calling:
Feature: Custom Karate Methods
This feature file contains Custom Karate Methods that can be called and used from other Feature Files
Background:
* def *nameofyourfunction* =
#Comment describing the fuction
"""
function() {
*code*
}
"""
****Scenario: This line is required please do not delete - or the functions cannot be called****
I think you've already seen the answer here, and this question is an exact duplicate: https://stackoverflow.com/a/47002604/143475 (edit: ok, maybe not)
Anyway, I'll repeat what I posted there:
there is no problem when you define multiple functions in one feature and call it from multiple other features
you will anyway need a unique name for each function
when you use call for that feature, all the functions will be available, yes, but if you don't use them, that's okay. if you are worrying about performance and memory, IMHO that is premature optimization
if that does not sound good enough, one way to achieve what you want is to define a Java class Foo with a bunch of static methods. then you can do Foo.myMethodOne(), Foo.myMethodTwo() to your hearts content. I would strongly recommend this approach in your case, because you seem to be expecting an explosion of utility methods, and in my experience, that is better managed in Java, just because you can maintain that code better, IDE support, unit-tests, debugging and all
Hope that makes sense !

How to find a standard text within a SapScript or SmartForm?

I need to track down where within a large number of custom sapscripts and smartforms a specific standard text (SO10) is being used.
Apart from the equivalent of "check the code for each print script", I've not found a workable solution online. Any suggestions?
After posting, I found a partial solution. The code below will search for a standard text within sapscripts, but not smartforms.
PARAMETERS: p_sttxt LIKE stxh-tdname.
DATA: BEGIN OF t_stxh OCCURS 0,
tdname LIKE stxh-tdname,
tdspras LIKE stxh-tdspras,
END OF t_stxh.
DATA t_lines LIKE tline OCCURS 0 WITH HEADER LINE.
SELECT tdname tdspras FROM stxh INTO TABLE t_stxh
WHERE tdobject = 'FORM'
AND tdid = 'TXT'
AND tdspras = 'E'.
LOOP AT t_stxh.
REFRESH t_lines.
CALL FUNCTION 'READ_TEXT'
EXPORTING
* CLIENT = SY-MANDT
id = 'TXT'
language = t_stxh-tdspras
name = t_stxh-tdname
object = 'FORM'
TABLES
lines = t_lines
EXCEPTIONS
id = 0
language = 0
name = 0
not_found = 0
object = 0
reference_check = 0
wrong_access_to_archive = 0
OTHERS = 0 .
SEARCH t_lines FOR p_sttxt.
IF sy-subrc EQ 0.
WRITE:/ t_stxh-tdname, t_stxh-tdspras.
ENDIF.
ENDLOOP.
This is a (fixed) version of the code found here: http://scn.sap.com/thread/179142
What concerns SmartForms, you cannot. You cannot just find it like you want it.
Unfortunately, in such ̶g̶o̶o̶d̶ ̶o̶l̶'̶ legacy technology as SmartForms everything is working legacy way, and standard texts are simply hard-coded. Yes, it looks awkward but they are really hard-coded, and these names are written out to SmartForm FM code every time it is re-generated.
So the only workaround here is to analyze the code.
Find all FMs for existing Smart Forms in system
There is a D010INC table containing all forms with their includes. The main point here is that all SmartForm FMs start with /1BCDWB/ prefix.
The main logic is in the includes, so we need to find correspondent INCLUDE for the target form.
Fetch SF include source code
It can be done in a several ways: via CL_RECA_RS_SERVICES class, via table REPOSRC, but the simplest way is ABAP statement READ REPORT.
Search SO10 text element name in the source code
Get Smart Form names for the FMs from hit list. It can be done via STXFADMI table, like in below snippet, but the more correct way is SSF_FUNCTION_MODULE_NAME FM
Bingo!
Sample solution could look like this:
DATA: lt_source TYPE TABLE OF string,
lt_smartforms TYPE TABLE OF d010inc,
so_text TYPE char50,
fs_form TYPE string,
used_in TYPE TABLE OF string,
len TYPE i.
* populating the list of SmartForm FMs
SELECT * FROM d010inc AS d
INTO TABLE lt_smartforms
WHERE master LIKE '/1BCDWB/%'
AND include LIKE '/1BCDWB/%'.
so_text = '85XX_FOOTER'. " <- our SO10 text element name
LOOP AT lt_smartforms ASSIGNING FIELD-SYMBOL(<fs_fm_name>).
* reading FM source code
READ REPORT <fs_fm_name>-include INTO lt_source.
* checking if SO11 exists in source code
FIND FIRST OCCURRENCE OF so_text IN TABLE lt_source.
IF sy-subrc = 0.
len = strlen( <fs_fm_name>-include ) - 7.
* searching for SmartForm related to the target FM
SELECT SINGLE formname
FROM stxfadmi
INTO fs_form
WHERE fmnumb = <fs_fm_name>-include+len(4).
IF sy-subrc = 0.
APPEND fs_form TO used_in.
ENDIF.
ENDIF.
ENDLOOP.
Yes, it is junky, not elegant and awkward, but who said it should be so?

Hiding data from a text file in a image file using dwt steganography

The code below hides the text "helloworld" in the two specified DWT coefficients using steganography. I have been trying to adapt the code to hide data contained in a .txt file. I have been working on this for a while but cant seem to get anything to work correctly. Can anyone help please?
clear all;
close all;
dataToHide = 'helloworld';
wavename = 'haar';
data = zeros(1,length (dataToHide));
for i =1 : length(dataToHide);
d = dataToHide (i)+0;
data (i) = d;
end
im=imread ('cameraman.tif');
%imshow(im);
[cA1, cH1,cV1, cD1]= dwt2(im,wavename);
A1 = upcoef2('a',cA1,wavename,1);
H1 = upcoef2('h',cH1,wavename,1);
V1 = upcoef2('v',cV1,wavename,1);
D1 = upcoef2('d',cD1,wavename,1);
subplot(2,2,1); image(wcodemat(A1,192));
title ('A1');
subplot(2,2,2); image(wcodemat(H1,192));
title ('H1');
M=max(data);
normilize = data/M;
n=length(data);
cH1 (1,1) = -1*(n/10);
cH1 (1,2) = -1*(M/10);
[~ , y] =size(cH1);
for i = 1 : ceil(n/2)
cV1 (i,y) = normilize(i);
end
for i= ceil(n/2)+1 :n;
cD1 (i,y) = normilize(i);
end
Update
I can know read text from the file.However, I have come across another problem. When I read from file I want to convert the text to binary (name=dec2bin(dataToHide). The above code doesn't want to hide binary data for me?? I am very new to matlab & steganography/watermarking. I have been doing lots of research regarding LSB embedding in the discrete wavelet transform. However, the code above, which I took from the web is manipulating subband coefficients, but from what I can read from the code it is not doing it by LSB replacement. (i.e replace LSB of cover image with MSB of the secret data file). Can anyone recommend some code for me to look at that works by LSb wavelets embedding?